什么是策略模式?
定义算法族,分别封装起来,让他们可以互相替换,从而让算法的变化独立于实用算法的客户。
举个例子:
鸭子,它会叫,有的会飞,要建立鸭子的模型,伪代码如下:
传统结构
首先是一个 Duck 超类,有 name 属性,和 fly、quark 两个方法,所有的鸭子都去实现这个 Duck,实现 fly、quark 两个方法。
这样做有两个弊端:
- 每个实现类都要重写 fly、quark;
- fly、quark 不能复用,例如上图: RedDuck 和 GreenDuck 都是 “嘎嘎叫”,却要实现两次。
像这样的结构,既有相同的部分(如: name),又会有不同的行为(fly、quark),为了提高程序复用性和可维护性,可以利用 策略模式 进行改造。
在编程中,比较实用的一条原则:将变化的部分和不变的部分分离开来。在本例中,将 fly、quark抽取为接口,然后由具体实现定义行为:
fly行为
quark行为
Duck 中定义两个行为变量,并在 fly、quark 中,调用变量的 fly、quark。
新的Duck
现在,Duck 和它的子类就可以和 fly、quark 解耦了。在使用时,可以通过构造方法或者 setter,设置flyBehavior、quarkBehavior 为对应的行为实现类对象,就可以完成“飞行”和“叫”这两个行为。这样行为组就可以复用,并且可以灵活组合。
总结
现在,再对照着例子回头看一下 策略模式 :定义算法族,分别封装起来,让他们可以互相替换,从而让算法的变化独立于使用算法的客户。
在演示中,fly、quark被抽取成接口(FlyBehavior,QuarkBehavior),它们就可以称为算法族,通过设置对象(Duck)的属性(flyBehavior,quarkBehavior)实现不同的行为。如 flyBehavior 属性,可以根据需要设置为 FlyUnable 或 FlyWithWing,是可以替换的。
这样看来,代码量好像反而增加了,但是如果需求在不断的膨胀,这种模式的的优势就越来越明显。在传统结构中,每种鸭子都要实现方法,而且有可能实现的内容会重复,代码堆积越来越多;改造之后,每种鸭子只需继承 Duck,只要关注 flyBehavior,quarkBehavior 两个属性就好了。
- 将变化的部分抽取出来,解耦
- 算法族可以灵活组合
- 代码复用性高
- 方便维护
网友评论