[设计模式]策略模式

来源:互联网 发布:e店宝软件下载 编辑:程序博客网 时间:2024/06/16 13:03

感谢《Android源码设计模式解析与实战》 何红辉 关爱民 著

实现某一个功能可以有多种算法或者策略,我们根据实际情况选择不同的算法或者策略来完成该功能,例如:排序算法 可以使用 插入排序、冒泡排序等;针对这种情况,一种方法是将多种算法写在一个类中。例如可以将这些算法写到一个类中,每一个方法对应一个具体的算法, 一种是将这些算法封装在一个统一的方法中,通过if..else或者switch条件判断来选择具体的算法。这两种方法我们称之为硬编码,这两种方式的缺点是:当很多算法集中在一个类中时,这个类就会变得臃肿,类的维护成本 会变高,维护时更容易引发错误,如果我们需要增加一种新的排序算法,需要修改封装算法类的源代码。这样就违反了OCP原则和单一原则。

如果将这些算法或者策略抽象出来,提供一个统一的接口,不同的算法或者策略有不同的实现类,这样在程序客户端就可以通过注入不同的实现对象来实现算法或者策略的动态替换,这种模式的可扩展性、可维护性也就更高。这就是策略模式。


通过建立抽象,将不同的策略构建成一个具体的策略实现,通过不同的策略实现算法替换。在简化逻辑、结构的同时,增强了系统的可读性、稳定性、可扩展性,这对于较为复杂的业务逻辑显得更为直观,扩展也更为方便。


定义

笔画种模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。


使用场景

1.针对同一类型问题的多种处理方式,仅仅是具体行为有差别时。

2.需要安全地封装多种同一类型的操作时。

3.出现同一抽象有多个子类,而又需要使用if..else或者switch来选择具体子类时。


UML类图

Context  :用来操作策略的上下文环境;

Strategy :策略的抽象;

ConcreteStragety:具体的策略实现;


示例

Stragety 策略的抽象

public interface CalculateStrategy {/** * 按距离计算价格 * @param km * @return 返回价格 */int calculatePrice(int km);}
ConcreteStragety 具体的策略实现

/** * 公交价格计算策略 * @author Administrator * */public class BusStrategy implements CalculateStrategy {/** * 十公里之内一元钱,超过十公里之后每加一元钱可以乘5公里 */@Overridepublic int calculatePrice(int km) {//超过十公里的距离;int extraTotal = km -10;//超过的距离是五公里的倍数int extraFactor = extraTotal / 5;//超过的距离对5公里取余int fraction = extraTotal % 5;//计算价格int price = 1 + extraFactor * 1;return fraction > 0 ? ++price : price;}}
/** * 地铁价格计算策略 * @author Administrator * */public class SubwayStrategy implements CalculateStrategy {/** * 6公里(含)内3元,,6~12公里(含)mw 4元,12~22(含)5元,22~32(含)6元 */@Overridepublic int calculatePrice(int km) {if(km <= 6){return 3;}else if(km > 6 && km <= 12){return 4;}else if(km > 12 && km <=22){return 5;}else if(km > 22 && km <= 32){return 6;}return 7; //其他}}
Context 用来操作策略的上下文环境

public class TranficCalculator {private CalculateStrategy mStrategy;public static void main(String[] args) {TranficCalculator calculator = new TranficCalculator();calculator.setStrategy(new BusStrategy());System.out.println("公交乘12公里的价格" + calculator.calculatePrice(12));}private void setStrategy(CalculateStrategy strategy) {this.mStrategy = strategy;}private int calculatePrice(int km){return mStrategy.calculatePrice(km);}}


去掉了各种各样的判断语句,结构变的清晰,在隐藏实现的同时,可扩展性变得很强,例如当我们需要增加出租车的计算策略,只需要添加一个出租车计算策略类,然后将该策略设置给TranficCalculator(Context)即可。

/** * 出租车计算策略 * @author Administrator * */public class TaxiStrategy implements CalculateStrategy {@Overridepublic int calculatePrice(int km) {return km * 1;}}
将策略注入到TranficCalculator中即可

public class TranficCalculator {private CalculateStrategy mStrategy;public static void main(String[] args) {TranficCalculator calculator = new TranficCalculator();//calculator.setStrategy(new BusStrategy());calculator.setStrategy(new TaxiStrategy()); //注入新策略System.out.println("公交乘12公里的价格" + calculator.calculatePrice(12));}private void setStrategy(CalculateStrategy strategy) {this.mStrategy = strategy;}private int calculatePrice(int km){return mStrategy.calculatePrice(km);}}


总结

策略模式主要用来分离算法,,在相同的行为抽象下有不同的具体实现策略。这个模式好的演示了开闭原则,也就是定义抽象,注入不同的实现,从而达到很好的扩展性。


优点

1.结构清晰明了,使用简单直观;

2.耦合度相对而言较低,扩展方便;

3.操作封装也更为彻底,数据更为安全;


缺点

随着策略的增加,子类也会变得繁多;













0 0
原创粉丝点击