兵无常势,水无常形,能因敌变化而取胜者,谓之神! ——《孙子兵法》

故事背景

旅行开始,我和设计模式mm要去的目的地很多,去往不同目的地可以选择的交通工具也是多样的,从北京到上海,我们可以选择自驾游、乘坐飞机、高铁,甚至是骑单车等等方式!每一种交通工具到达目的的时间也不同,假如从北京到上海,乘坐飞机两个小时,高铁五个小时,自驾游3天(3*24小时),每一种交通费也不一样!

假设如下,要完成1公里的路程,不同交通方式使用的时间不同!
1公里: 飞机 需要 1分钟
1公里: 高铁 需要 10分钟
1公里: 汽车 需要 30分钟
1公里: 自行车 需要 60分钟

public class TravelHappy{private int kilometers;//公里private String travelType;//交通工具类型public TravelHappy(){}public TravelHappy(int kilometers,String travelType){this.kilometers = kilometers;this.travelType = travelType;}//get set ..//计算花费的时间public int travelCostTime(){if("airplane".equals(this.travelType)){System.out.println("使用 "+ this.travelType + " 完成旅行...");return kilometers * 1;}else if("High_Speed_Rail".equals(this.travelType)){System.out.println("使用 "+ this.travelType + " 完成旅行...");return kilometers * 10 ;}else if("car".equals(this.travelType)){System.out.println("使用 "+ this.travelType + " 完成旅行...");return kilometers * 30 ;}return 0;}}public class Client{public static void main(String args[]){TravelHappy th = new TravelHappy();System.out.println("从北京到上海 1000公里");th.setKilometers(1000);th.setTravelType("airplane");int costTime;costTime = th.travelCostTime();System.out.println("-------costTime-------------" + costTime);System.out.println("--------------------");th.setTravelType("car");costTime = th.travelCostTime();System.out.println("-------costTime-------------" + costTime);}
}从北京到上海 1000公里
使用 airplane 完成旅行...
-------costTime-------------1000 分钟
--------------------
使用 car 完成旅行...
-------costTime-------------30000 分钟

通过上面的例子,我们可以计算出使用不同的交通工具从一个地方到另一个地方所花费的时间。
每一种交通工具的使用其实就是一种策略,或者称为一种算法,但是上面的通过travelCostTime 来计算使用交通工具花费的时间并不是一个好的或者说完美的方案,存在一些问题。
- 如果要增加新的工具花费时间的计算,就要修改travelCostTime代码,违反了“开闭原则”,系统的灵活性和可扩展性不高。
- 如果增加的算法太多,就会造成太多的if..else… ,不利用维护。
- 也利于算法的重用,如果另外一个地方需要使用这个计算模式,需要拷贝粘贴来重用!

要解决上面的这些问题,设计模式MM推荐我看看策略模式。

故事主角-策略模式

策略模式: 定义了算法族,将算法分别封装起来,让他们之间可以互相替换,让算法的变化独立于具体使用算法的环境。

  • 算法封装起来,找到应用中可能需要变化的部分独立出来。
  • 可以互相替换,面向超类型编程,也就是面向抽象编程。
  • 算法的行为和具体使用的环境分别,方便算法可以重用。

  • Context(环境类):环境类是使用算法的的角色,它在解决某个问题的时候可以采用多种策略。在环境类中维持一个抽象类的引用实力,用于定义采用的策略。
  • Strategy(抽象策略类):声明算法的抽象方法,是所有策略类的父类,可以是抽象类也可以是接口。环境类通过抽象策略类中声明的方法在运行时候调用具体策略类中的算法。
  • ContreteStrategy(具体策略类):实现抽象策略类中的方法,并定义自己的算法。

简要伪代码:

class abstract Strategy{public abstract int costTime();
}class ContreteStrategyA extends Strategy{public int costTime(){//...具体的算法}
}class Context{private Strategy strategy;//get set...public int travelCostTime(){return  strategy.costTime();}}class Cinent{Context context = new Context();  Strategy strategy;  strategy = new ConcreteStrategyA(); //可在运行时指定类型  context.setStrategy(strategy);  context.travelCostTime();
}

武功修炼后

根据对策略模式的学习后,设计模式MM让我重新实现一下刚开始设计的TravelHappy,好吧!

public abstract class TravelStrategy {public abstract int costTime(int km);
}public class AirPlaneTravelStrategy extends TravelStrategy {@Overridepublic int costTime(int km) {return km * 1;}
}public class CarTravelStrategy extends TravelStrategy {@Overridepublic int costTime(int km) {return km * 1;}
}public class CarTravelStrategy extends TravelStrategy {@Overridepublic int costTime(int km) {return km * 30 ;}
}public class TravelHappy {private TravelStrategy strategy;public TravelHappy(TravelStrategy strategy){this.strategy = strategy;}public int travelCostTime(int km){return strategy.costTime(km);}
}public class Client {public static void main(String args[]){TravelStrategy strategy;TravelHappy th;//这里的策略可以使用配置文件进行读取strategy = new AirPlaneTravelStrategy();th = new TravelHappy(strategy);System.out.println("从北京到上海 1000公里");int costTime;costTime = th.travelCostTime(1000);System.out.println("-------costTime-------------" + costTime +" 分钟");System.out.println("--------------------");//这里的策略可以使用配置文件进行读取strategy = new CarTravelStrategy();th = new TravelHappy(strategy);costTime = th.travelCostTime(1000);System.out.println("-------costTime-------------" + costTime +" 分钟");}
}从北京到上海 1000公里
使用飞机.......
-------costTime-------------1000 分钟
--------------------
使用汽车.......
-------costTime-------------30000 分钟

此时如果需要增加一个高铁的计算时间方法,原有代码均无须修改,只要增加一个新的高铁策略类作为抽象类的子类,实现在抽象类中方法,然后在客户端使用(客户端要使用配置文件方式进行读取),完全符合“开闭原则”。

故事结局

通过上面简单的对策略模式武功的学习,下面总结一下:
策略模式用于算法直接的自由切换和扩展,使用范围比较广泛。策略模式对应解决某一问题的算法族,允许用户从一个算法族中任意选择其中一个算法来解决某一个问题,同时可以方便的新增新的算法。

优点:
- 符合“开闭原则”,在不修改原有系统的基础上选择算法或者行为,并能灵活的扩展算法。
- 使用策略模式,避免了多重条件选择语句,方便系统维护。
- 将具体的策略提取并独立出来,可以在不同的环境类中复用,减少代码冗余,复用性更高。

缺点:
- 客户端必须要知道所有的策略类,自行决定使用哪一种策略。客户端在使用的时候就要知道每一种算法的区别,增加客户端使用难度。
- 如果策略比较多,会产生很多具体的策略类
- 客户端每次只可以使用一个策略类,使用多个策略类需要一个策略使用完在使用下一个。

使用场景:
- 客户端系统需要动态的在几种算法中选择一种。
- 如果算法有保密和安全性,不希望客户端知道,客户端只需要知道算法是做什么功能的即可。

实际生活场景:如超市商品的打折策略,一般游戏中选择难度级别(初级、、中级、高级),不同级别对应不同的实现策略。

到此策略模式告一段落,这篇内容对应策略模式就是初级级别。不管咋,设计模式MM告诉我不着急,一口气吃不成大胖子,一步也从北京跨不到上海,饭要一口一口吃,路要一步一步走。

Next 期待下一篇吧!! 在这么浪漫的旅途中,肯定会有很多人关注,下一篇介绍 观察者模式——关注我,分享旅途最浪漫的瞬间!

参考

  • 史上最全设计模式导学
  • 《图解设计模式》
  • 《Head First 设计模式》

本专栏文章列表

一、设计模式-开篇—为什么我要去旅行? #和设计模式一起旅行#
二、设计模式-必要的基础知识—旅行前的准备 #和设计模式一起旅行#
三、设计模式介绍—她是谁,我们要去哪里? #和设计模式一起旅行#
四、单例模式—不要冒充我,我只有一个! #和设计模式一起旅行#
五、工厂模式—旅行的钱怎么来 #和设计模式一起旅行#
六、策略模式—旅行的交通工具 #和设计模式一起旅行#
七、观察者模式——关注我,分享旅途最浪漫的瞬间! #和设计模式一起旅行#
八、装饰者模式—巴厘岛,奶茶店的困扰! #和设计模式一起旅行#
九、命令模式—使用命令控制奶茶店中酷炫的灯 #和设计模式一起旅行#
十、模板方法模式—制作更多好喝的饮品! #和设计模式一起旅行#
十一、代理模式 —专注,做最好的自己!#和设计模式一起旅行#
十二、适配器模式——解决充电的烦恼 #和设计模式一起旅行#
十三、外观模式—— 简化接口 #和设计模式一起旅行#
十四、迭代器模式—— 一个一个的遍历 #和设计模式一起旅行#
十五、组合模式—— 容器与内容的一致性 #和设计模式一起旅行#
十六、状态模式—用类表示状态 #和设计模式一起旅行#
十七、访问者模式-访问数据结构并处理数据 #和设计模式一起旅行#
十八、职责链模式-推卸责任,不关我的事,我不管!#和设计模式一起旅行#
十九、原型模式—通过复制生产实例 #和设计模式一起旅行#
二十、设计模式总结—后会有期 #和设计模式一起旅行#


如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到,谢谢!

如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!


欢迎访问我的csdn博客,我们一同成长!

不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

博客首页 : http://blog.csdn.net/u010648555

六、策略模式—旅行的交通工具 #和设计模式一起旅行#相关推荐

  1. java策略模式详解_Java经典设计模式之策略模式原理与用法详解

    本文实例讲述了Java经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式 ...

  2. python策略模式的应用_Head First 设计模式——策略模式(Strategy Pattern)——Python实现 | 学步园...

    作者:liuyuan_jq 2011-06-13 策略模式定义 定义了 问题 J o e 上班的公司做了一套相当成功的模拟鸭子游戏: SimUDuck.游戏中会出现各种鸭子,一边游泳戏水,一边呱 呱叫 ...

  3. 十八、职责链模式-推卸责任,不关我的事,我不管!#和设计模式一起旅行#

    不在其位,不谋其政! –出自<论语·泰伯> 故事背景 在现实世界中,有很多情况下会遇到一些推卸责任的场景,比如要办理一件事的时候,被告诉你要去做个做这个事情,但是去了这个地方,确告诉要到另 ...

  4. 五、工厂模式—旅行的钱怎么来 #和设计模式一起旅行#

    君子爱财,取之有道!-- 出自<增广贤文> 故事背景 上一篇我和MM相约好了,去旅行了,但是旅行是需要Money的啊,作为有个搬砖的码农,没钱啊,怎么呢!不能穷游啊,真是愁人啊 !哎 ,办 ...

  5. 八、装饰者模式—巴厘岛,奶茶店的困扰! #和设计模式一起旅行#

    善于思考,方法总比问题多! 故事背景 我和漂亮的模式MM来到巴厘岛,这里火山爆发刚刚结束不久,一切要重新开始,来到这个地方几天后,觉得这个地方还是不错,于是就决定在这里开一个奶茶店,因为这里游客比较多 ...

  6. 十二、适配器模式——解决充电的烦恼 #和设计模式一起旅行#

    轻轻的我走了, 正如我轻轻的来: 我轻轻的招手, 作别西天的云彩. --徐志摩 <再别康桥> 故事背景 把奶茶店盘了出去,我和设计模式MM,继续上路,坐着冒着烟的飞机来到了剑桥,这里真是个 ...

  7. 二、设计模式-必要的基础知识—旅行前的准备 #和设计模式一起旅行#

    必要的基础知识-旅行前的准备 工欲善其事,必先利其器.--<论语> 要开始一场旅行,准备的工作肯定不能少,不能太任性,一场说走就走的旅行,也需要基础条件的,那么本次就做做一些旅行之前的准备 ...

  8. 【设计模式】策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

    文章目录 一.策略模式简介 二.策略模式适用场景 三.策略模式优缺点 四.策略模式与其它设计模式 五.策略模式代码示例 1.促销策略接口 2.满减促销策略 3.返现促销策略 4.空促销策略 5.促销策 ...

  9. 【Java设计模式】策略模式

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景知识 策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法.比如每 ...

最新文章

  1. Linux之文本搜索命令 grep
  2. Windows Server 2008 R2 如何启动内核调试
  3. 关于c数据类型的范围
  4. Win32汇编笔记-消息基础
  5. UA MATH567 高维统计专题1 稀疏信号及其恢复2 用L1-norm作为L0-norm的convex relexation
  6. 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高...
  7. java类加载过程_面试官:java类的加载过程
  8. (Joomla)字符串截取
  9. mysql迁移到mariadb_项目从MYSQL迁移至MARIADB教程
  10. 安全漏洞——如何查找和修复它们
  11. jquery-easyui中datagrid扩展,隐藏显示表头功能
  12. 判断对象是否超出屏幕
  13. ICPC程序设计题解书籍系列之二:刘汝佳:《算法竞赛入门经典训练指南》
  14. 2016年物联网技术将从概念走向落地
  15. Spring框架学习---Spring Framework下篇
  16. 如何按行政区划下载谷歌地图并裁剪
  17. php 调用 百度句法分析,【原创源码】百度新版翻译API调用使用范例
  18. 使用git上传代码遇到关于remote: Support for password authentication was removed on August 13, 2021.的问题
  19. 逆透视变换(IPM)多种方式及代码总结
  20. java线程池newfi_Java 线程池中的线程复用是如何实现的?

热门文章

  1. P2P关卡——资金存管与资金托管
  2. 《大数据时代》 概要
  3. Java memory stream 内存流
  4. Python JPG图片转DCM
  5. 逻辑运算是计算机实现计算器基础,第1章__计算机的发展与运算基础.ppt
  6. 软考 - 软件设计师 - 下午-案例分析 做题技巧与考点整理
  7. cocos做飞机大战笔记【根据道具设置子弹】
  8. Android精通教程V
  9. 睿呈时代与袋鼠云签署战略合作协议,携手助推传统行业数字化转型
  10. Java调用Python语言及第三方Python库