假使我们正在做一个语音助手,我们的语音助手能够查询天气,播放音乐,拨打电话...我们有一个Manager类用于管理天气、音乐、电话模块。使用流水线的开发是当传递来的是天气的代码,我们可以用if...else或者switch...case来判断它应该分发到哪个模块。但是如果业务增多,我们就需要不停的添加判断分支,会造成代码的冗余,不符合设计原则的开闭原则,此时我们可以使用策略模式。
策略模式的主要优点如下。
1. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if...else 语句、switch...case 语句。
2. 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
3. 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
4. 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
5. 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。
其主要缺点如下。
1. 客户端和服务端需要对策略类有一个共识,以便适时选择恰当的算法类。
2. 策略模式造成很多的策略类,增加维护难度。
- 我们将各模块业务抽象成一个BaseModel接口,含有一个方法execute()用于执行逻辑:
//抽象策略
interface BaseModel{
fun execute()
}
- 各模块继承该接口,并在实现execute()方法用于处理自己的逻辑:
//具体策略
calss WeatherModel : BaseModel{
override fun execute(){
println("天气模块处理")
}
}
calss MediaModel : BaseModel{
override fun execute(){
println("媒体模块处理")
}
}
calss CallModel : BaseModel{
override fun execute(){
println("通话模块处理")
}
}
- 我们使用一个Manager单例对象用于处理对应的消息应该进入哪一个策略:
//策略处理
object Manager{
var model: BaseModel? = null
fun execute(){
if(model.initialized()){
model.execute()
} else {
println("model not init!")
}
}
fun <T> T.initialized() :Boolean{
return this != null
}
}
- 传递指定的对象到管理对象中,管理对象就可以执行对应的方法了,而不需我们手动判断
object Main{
@JvmStatic
fun main(args: Array<String>) {
Manager.model = WeatherModel()
StrategyContext.strategyMethod()
}
}
//输出了 天气模块处理
评论 (0)