strategy pattern的定义
- 定义一组算法,分别封装起来,让它们之间可以互相替换。Strategy pattern让算法的变化独立于使用它的客户端。
- 在接口中定义抽象,在它的derived类中实现相应的细节。
在面向对象程序设计中,其中一个重要的原则就是针对接口编程,不要去针对实现编程。 下图说明了怎样实现这个原则:
从上图可以看出:在接口中封装抽象,在它的derived类中实现相应的细节。Client针对接口编程,当derived类的数量改变时,Client代码不受影响;当derived类的实现细节改变时,Client代码同样也不受影响。
利用strategy pattern可以很好地针对这样的原则去编程。下面我来用具体的代码举个例子。
Example
相信大家都去KFC吃过东西吧。那么现在KFC有个活动,第一杯可乐正常价格,之后的每杯可乐都是半价。针对这个业务需求,我设计一个结账策略接口,它封装了getActPrice方法,代码如下:
|
|
由于有两种价格策略,因此这里我写两个derived类,并分别实现具体的细节。
|
|
现在,让我们设计顾客实体。
|
|
假设我们每杯可乐的原始价格为10元,现在有一个客户买了3杯可乐,现在让我们算一算他总共需要付多少钱吧?
|
|
至此,整个例子已经演示完了。大家可以认真想一想,用Strategy Pattern设计的好处是什么呢?如果未来某一天,我们推出个新的价格活动,比如第三杯1/4价格,我们只需要写一个价格类实现BillingStrategy接口就行了,并不需要去修改客户端的代码。这大大降低了我们软件的维护成本。
Java中用到Strategy Pattern的地方
java.util.Comparator#compare() 与 Collections#sort()
下面我举个关于这个Java API的例子。
|
|
接口Comparator只定义了Sort方法的抽象,我们可以定义不同的derived类分别实现各自不同的sort细节。而Collections的sort方法定义方法签名并不需要提前知道具体的sort细节,它只需要定义Comparator接口,具体的实现会等到运行时找相应的derived类实现,这是一个很漂亮的例子,非常值得学习。