持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
前言
在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。
正文
策略模式
策略模式,就是定义一系列功能,把它们一个个封装起来, 并且使它们可相互交换,从而不影响整体。
很多时候,在咱们开发的过程中就会遇到这种情况,比如,开发A功能完成后,又要开发一个B功能,能让用户在A和B功能直接切换,过段时间后,又要开发C功能,同样可以切换A、B和C。要完成这项工作,就需要很多种if...else判断,策略模式就可以优化。
现实中的例子就是,你想去机场,当你去搜索去机场的路线时,导航就会有多种方式让你选择,开车、公共交通、打车。时间和花费都不相同。这就是给你选择的策略,当你选择花费最少时,系统就会帮你决定用那种方式出行。
下面,咱们再来看代码的例子,实现一个计算功能。
首先定义一个策略协议(Strategy
),里面定义一个操作函数(operation
)返回Int
类型
protocol Strategy {
func operation(a: Int, b: Int) -> Int
}
定义三个操作方法分别是加(OperationAdd
)、减(OperationSubstract
)、乘(OperationMultiply
),然后实现对应的操作函数(operation
)
class OperationAdd: Strategy {
func operation(a: Int, b: Int) -> Int {
a + b
}
}
class OperationSubstract: Strategy {
func operation(a: Int, b: Int) -> Int {
a - b
}
}
class OperationMultiply: Strategy {
func operation(a: Int, b: Int) -> Int {
a * b
}
}
然后定义一个中间者,用于实例化后,进行对应操作。
class Context {
private var strategy: Strategy
init(strategy: Strategy) {
self.strategy = strategy
}
func executeStrategy(a: Int, b:Int) {
strategy.operation(a: a, b: b)
}
}
接下来,咱们来看实现
var context = Context(strategy: OperationAdd())
print("10 + 5 = (context.executeStrategy(a: 10, b: 5))")
context = Context(strategy: OperationSubstract())
print("10 - 5 = (context.executeStrategy(a: 10, b: 5))")
context = Context(strategy: OperationMultiply())
print("10 * 5 = (context.executeStrategy(a: 10, b: 5))")
输出:
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50
可以看出,只要有新的策略,只用继承Strategy
,然后实现operation
方法,就可以正常使用了,不用再去做一系列if...else 的方法了。
结语
策略模式适合应用场景
- 当你想使用对象中各种不同的算法变体, 并希望能在运行时切换算法时, 可使用策略模式。
- 当你有许多仅在执行某些行为时略有不同的相似类时, 可使用策略模式。
- 如果算法在上下文的逻辑中不是特别重要, 使用该模式能将类的业务逻辑与其算法实现细节隔离开来。
策略模式优缺点
优点
- 可以在运行时切换对象内的算法。
- 可以将算法的实现和使用算法的代码隔离开来。
- 可以使用组合来代替继承。
- 开闭原则。 你无需对上下文进行修改就能够引入新的策略。
缺点
- 如果你的算法极少发生改变, 这个模式并不适用
- 客户端必须知晓策略间的不同——它需要选择合适的策略。
扩展阅读 下面还有其他模式