这个模式可以替代写 if else
。
我们使用的app大多都有分享的功能,我们可以选择分享到不同的地方,比如微博、微信、QQ等等,虽然是同一个内容,但是分享到不同的平台就会有不同的处理方式,比如要跳转到不同的app或者直接复制链接等等。如果让你来实现这个功能,你会如何实现呢?
1 | public void Share{ |
如果只是写一个这么简单的功能,那么这样的代码也未尝不可,因为这样的代码量不多,后续也不需要怎么拓展和修改,维护起来也不算麻烦。但是,我们工作中遇到的都是一些比较复杂的项目,要保证项目的可读性、可维护性和可拓展性,就必须在代码上下功夫了。
策略模式中有哪些角色。
Strategy
(策略)Strategy
角色负责决定实现策略所必需的接口(API)。在示例程序中,由strategy
接口扮演此角色。
ConcreteStrategy
(具体的策略)ConcreteStrategy
角色负责实现Strategy角色的接口(API
),即负责实现具体的策略(战略、方向、方法和算法)。
Context
(上下文)- 负责使用
Strategy
角色。Context
角色保存了ConcreteStrategy
角色的实例,并使用ConcreteStrategy
角色去实现需求(总之,还是要调用Strategy
角色的接口(API))。
- 负责使用
介绍到这里,相信你对策略模式有了初步的认识,那我们就用策略模式来重构前面的代码,让你加深对策略模式的理解。
1 | //定义策略接口 |
1 | public void Share{ |
再回忆一下策略模式中的各个角色,代码中的DealStrategy
接口就是策略,DealSina
和DealWeChat
是具体的策略,DealContext
就是使用策略的上下文。
所以这样的代码已经符合策略模式的代码结构了。我们通过策略模式将策略的定义、创建、使用解耦,让每一部分都不至于太复杂,也去除了if...else
这样的条件判断语句,代码的可维护性和可拓展性都提高了。
我们把可变的部分放到了Share
类中的静态代码段中。如果有新的需求,要添加一个分享的方式时,只需要定义好具体的策略,然后修改 Share
类中的静态代码段,其他代码都不需要修改。
优点
- 算法可以自由切换
- 避免使用多重条件判断
- 扩展性良好。
缺点
- 策略类会增多
- 所有策略类都需要对外暴露。
使用场景
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
- 一个系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。