参考资料:
概念解析
策略模式strategy,对象行为型
实现一个功能有多种算法或者策略,可以依据环境或者条件的不同选择不同的算法或者策略来完成此功能。
比如查找、排序等。
常用的编码方式:
1. 创建一个类,在类中提供多个方法,每个方法对应一个具体的查找方法。一个简单的例子,DateUtils工具类,获取时间的方式有很多种,对外提供很多获取时间的方法。
2. 或者是将查找,排序的算法封装在一个统一的方法中,通过if else的方法进行选择,比如if(冒泡){
冒泡的方法}else if(倒序){
倒序的方法}
以上这2中都是硬编码,如果需要新增一个新的查找或者排序算法,那么就要修改封装的算法类的源代码DateUtils;如果是更换了算法,比如DateUtils.getYear()更改名称成DateUtils.loadYear(),那么客户端也要修改调用的代码。这样在这个类中就会封装大量的查找算法,越来越复杂,维护起来也会变得很困难。
headfirst书上的例子拿来用一下:
一只鸭子,它的行为模式:可以飞fly()、叫duack()、走walk()、游泳swim()。
但是鸭子是有很多种的:真的鸭子,洗澡的玩具鸭,小黄鸭,墙上的涂鸦等,这些鸭子有的可以飞,有的不能遇水,有的不能叫。
而且就duack而言,也有很多种叫法,有的嘎嘎嘎,有的呀呀呀。。。
那么如何设计这个鸭子对象,让其产生的子鸭子可以飞,可以叫,而且发出不同的叫声呢?这里就可以用到策略模式来设计。
整体思路就是抽取鸭子的行为(算法),也就是算法(具体行为)和对象(鸭)分离。策略模式把对象本身和运算规则区分开来,定义一系列的算法,把每个算法封装起来,并且使其可以相互替换。也就是一个鸭子可以设定为嘎嘎叫,也可以替换为呀呀叫。
应用场景
直接上应用的场景吧,大部分人应该关注的是这点,场景也不是绝对的。此部分参考百度百科
1. 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为(鸭叫分为很多种)。
2. 需要在不同的情况下使用不同的策略(算法),或者策略还可能在未来用其他方式来实现(克隆出现了一只咩咩叫的鸭子)。
3. 对客户隐藏具体的策略(算法)的实现细节,彼此完全独立(可以不需要知道我怎么实现的叫声,只需要知道我提供了多少种叫法,调用就好了)。
模式的组成
例子
上图中定义了一个person,它要去旅游(旅游是一个行为动作),选择出行方式可以有很多种,飞机,火车,自行车。但是我们去实现这个person的时候并不要在这个类中实现所有的出行方式,而是通过一个接口方法。person中维护一个接口的调用。至于具体的出行(strategy.travel())的具体实现,就是具体的行为实现。
重点注意UML中的setStrategy(TravelStrategy strategy),通过改变Strategy来改变行为。TrainStrategy等都实现了TravelStrategy接口。
标准点的图: