开发者模式之—-策略者模式
2017-01-06 09:51
148 查看
开发者模式之—-策略者模式
—序言:本文为《Androdi源码及开发模式》的学习笔记。更详细内容请购买查看该正版书籍。在开发中,当一个任务有多个解决方案时,最简单的方式就是使用 if-else或者 switch -case来实现。但是如果因为if-else这种方法不会遵守开闭原则,所以耦合性很高,当要继续添加功能时,就要修改原来的代码。
而应对这种情况最好的方案就是使用策略者模式,把各种方案分离开来,让程序客户端根据具体的需求来动态选择不同的策略。
以下为策略者的UML图:
下面,我们来一出行时乘坐的交通工具票价计算来分析策略者模式的应用。
以下是最简单的用swtch-case实现的:
/** * author: ZK. * date: On 2016/12/18 * 用switch-case实现的计算器 */ public class NormalCalculator { public enum TrafficType { BUS, SUBWAY } private final String NORMAL_TAG = "----normal_tag"; public void calcutePrice(TrafficType trafficType, int km) { switch (trafficType) { case BUS: Log.d(NORMAL_TAG, km + "公里,公交车价格为:" + busPrice(km) + "元"); break; case SUBWAY: Log.d(NORMAL_TAG, km + "公里,地铁价格为:" + subwayBus(km) + "元"); } } private int busPrice(int km) { if (km < 5) { return 3; } else if (km > 5 && km < 10) { return 5; } else { return 8; } } private int subwayPrice(int km) { if (km < 6) { return 3; } else if (km > 6 && km < 12) { return 5; } else { return 7; } }
调用时,只需实例化NormalCalculator ,调用calculate方法就可以了。
NormalCalculator calculator = new NormalCalculator(); calculator.calcutePrice(NormalCalculator.TrafficType.TAXI,10);
代码看起来非常简单,直接调用calcute方法,传入交通类型和距离便可以得出价格了。但是现在我又有个需求了,现在我要添加计算出租车的价格这个需求,这时有人会说,这很简单嘛,不就再写一个taxi(int km)的方法,然后在calcute的switch里面添加相应的类型计算不就行了么。是的,确实看起来很简单,但我需求不停变化时,就需要不停地在原来的代码上修改,这样耦合性就非常高,很容易变得臃肿而且出错。
public class NormalCalculator { public enum TrafficType { BUS, SUBWAY, TAXI } private final String NORMAL_TAG = "----normal_tag"; public void calcutePrice(TrafficType trafficType, int km) { switch (trafficType) { case BUS: Log.d(NORMAL_TAG, km + "公里,公交车价格为:" + busPrice(km) + "元"); break; case SUBWAY: Log.d(NORMAL_TAG, km + "公里,地铁价格为:" + subwayBus(km) + "元"); break; case TAXI: Log.d(NORMAL_TAG, km + "公里,的士价格为:" + taxiPrice(km) + "元"); } } private int busPrice(int km) { if (km < 5) { return 3; } else if (km > 5 && km < 10) { return 5; } else { return 8; } } private int subwayBus(int km) { if (km < 6) { return 3; } else if (km > 6 && km < 12) { return 5; } else { return 7; } } private int taxiPrice(int km) { return km * 2; } }
好了,下面,大招来了。下面,我们来用策略者模式去实现这方案。
首先写一个计算器的接口,提供一个计算的方法:
public interface StrategyCalculator { int calculate(int km); }
好了。你要交通工具的计算方案?你自己去另外创建,你只要实现我这个接口,里面怎样的计算价格你自己实现就好。
公交车,是吗?
public class BusCalculator implements StrategyCalculator { @Override public int calculate(int km) { if (km < 5) { return 3; } else if (km > 5 && km < 10) { return 5; } else { return 8; } } }
地铁又怎样:
public class SubwayCalculator implements StrategyCalculator { @Override public int calculate(int km) { if (km < 6) { return 3; } else if (km > 6 && km < 12) { return 5; } else { return 7; } } }
出租车的需求来了,怕啥?妥妥的new class implement***,稳!
public class TaxiCalculator implements StrategyCalculator { @Override public int calculate(int km) { return km * 2; } }
好了,你要计算交通方式的价格?
StrategyCalculator calculator = new BusCalculator(); calculator.calculate(10);
注意,实例化的是你需要的计算器(BusCalculator),但调用者仍然是接口计算器(StrategyCalculator)。由父接口去调用方法,但具体实现还是由BusCalculator去处理。这样BusCalculator里面的实现就没必要暴露给外面知道,使用者只需调用我这接口的方法就可以了,具体内部自己会处理。点击calculate方法查看内部实现时,看到的只是接口的方法而已。如下:
从以上可以看到使用策略者模式,各个交通工具的计算器之间都是独立的,相互之间没有关联。当我需要增加一个交通工具是,你也是只需创建一个类实现这接口,重写方法就行了。这样在业务逻辑显得更为直观和简单的儿童诗,扩展也更为方便。
在Android源码中的策略者模式实现:
Android的动画过程中,切换的频率是不一定的,有可能是匀速,有可能是加速。这时动画就需要通过一个时间插值器实现这种效果。这时需求来了,我要匀速,我要加速的。我要时快是慢的,这时和上面的交通工具计算器是不是很类似。
示例代码链接:
设计模式Demo
相关文章推荐
- 初探开发者模式——Strategy模式(策略者模式)
- Windows Vista IE 7保护模式开发者生存指南
- 从C#的Singleton设计模式实现看.NET Framework特性对开发者的重要性
- 《设计模式 ● 策略者》之业务场景
- 桥接模式与策略者模式分析
- 一、策略者模式(Strategy Pattern)----2
- 模式——软件开发者的共同语言
- .NET设计规范:约定、惯用法与模式 :(第2版)(.NET开发者的必备图书,洞悉.NET技术内幕)
- Windows Vista IE 7保护模式开发者生存指南
- 盈利模式:从一款小应用看日本开发者大智慧
- 从C#的Singleton设计模式实现看.NET Framework特性对开发者的重要性
- magento -- 打开magento开发的调试模式(开发者模式)
- 设计模式笔记(23)---策略者模式(行为型)
- 设计模式笔记(23)---策略者模式(行为型)
- 软件开发者面试百问-----你知道设计模式吗?你用过哪些设计模式?在什么场合下用的?
- 从C#的Singleton设计模式实现看.NET Framework特性对开发者的重要性
- C#中不需要用锁的线程安全的Singleton设计模式开发者在线 Builder.com.cn 更新时间:2008-07-19作者: 来源:
- Windows Vista IE 7保护模式开发者生存指南
- 策略者模式解析 好理解的策略者模式
- 一、策略者模式(Strategy Pattern)----1