简单欢乐的依赖注入函数

依赖注入是一种很好的解耦代码并使其更容易测试的技术。您不必让对象自己创建自己的依赖项,而是从外部注入它们,使您能够针对各种情况进行不同的设置。 大多数时候,我们使用协议在Swift中启用依赖注入。虽然当我们的API更复杂时基于协议的依赖注入很好,但当它只有一个目的(并且只需要一个方法)时,我们可以通过简单地使用函数来降低我们的复杂性。 例如我们编写一个简单的英雄选择逻辑,我用使用randomizer从英雄池中随机的抽取英雄如下所示,最开始我们可能会这样写:

struct Hero {
    var name: String = "name"
    //...
}

class LOLGame {
    private let heros: [Hero]

    init(heros: [Hero]) {
        self.heros = heros
    }

    func randomHero() -> Hero {
        let index = Int(arc4random_uniform(UInt32(heros.count)))
        return heros[index]
    }
}

class AViewController: UIViewController {
    func chooseHero() -> Hero  {
        let manager = LOLGame(heros: [Hero(name: "剑圣"), Hero(name: "皇子"), Hero(name: "德玛")])
        return manager.randomHero()
    }
}

复制代码

如果我每次玩游戏时要更换选英雄的规则,怎么办呢?我们通常会再给LOLGame加上类似hero(at index:index) -> Hero 方法。但是如果我们能从外部注入依赖,情况看上去就会好得多,经过调整,代码如下

struct Hero {
    var name: String = "name"
    //...
}

class LOLGame {
    typealias Randomizer = (UInt32) -> UInt32

    private let heros: [Hero]
    private let randomizer: Randomizer
    
    init(heros: [Hero], randomizer: @escaping Randomizer = arc4random_uniform ) {
        self.heros = heros
        self.randomizer = randomizer
    }
    
    func selectedHero() -> Hero {
        let index = Int(randomizer(UInt32(heros.count)))
        return heros[index]
    }
}

class AViewController: UIViewController {
    func chooseHero() -> Hero  {
        let manager = LOLGame(heros: [Hero(name: "剑圣"), Hero(name: "皇子"), Hero(name: "德玛")])
        return manager.selectedHero()
    }
    
    func allowChooseJS() -> Hero {
        let manager = LOLGame(heros:  [Hero(name: "剑圣"), Hero(name: "皇子"), Hero(name: "德玛")]) {_ in 
            return 0
        }
        return manager.selectedHero()
    }
    
    func chooseHero(at index: UInt32) -> Hero {
        let manager = LOLGame(heros:  [Hero(name: "剑圣"), Hero(name: "皇子"), Hero(name: "德玛")]) {_ in
            return index
        }
        return manager.selectedHero()
    }
}
复制代码

这样改动后,可以在不动LOLGame的情况下,扩展功能。 这种定义API的好处在于"设计支持变化",如果API更复杂,还是通过协议启用依赖注入比较好,具体视情况而定,这里只是提供编程的一种思路。

如果您有任何问题,建议或反馈,请随时与我联系~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值