本文是对面向对象设计模式--策略模式的一个解析,主要分为定义解析、以案例-鸭子游戏对策略模式解析、多案例练习加深对策略模式的理解、最后总结整理知识要点与策略模式的一些优缺点或适用场景。

第一篇:定义解析

策略模式是GoF四人帮整理的《设计模式-可复用面向对象软件基础》一书中23种设计模式中归类为行为型模式中的一种,23种设计模式根据它们的用途分为三大类:5种创建型模式、7种结构型模式、11种行为型模式。

引自GoF四人帮对策略模式的定义与类图:

Strategy(策略模式):定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。

1)一系列算法或者也可以说是一个算法族,代表这些算法具有同一种特性。

如策略模式类图中具体算法实现ConcreteStrategyA、ConcreteStrategyB、ConcreteStrategyC都属于同一个接口Strategy的具体实现。

算法可以理解为能够解决某个问题或完成某个功能的方法,例如实现不同叫声行为的方法。

2)把它们一个个封装起来,蕴含着面向对象设计原则--封装变化。

OO设计原则:找出应用中可能需要变化之处,把它们独立起来,不要和那些不需要变化的代码混在一起。

通过封装变化原则,当应用需要变化的时候,只需要修改已经封装起来会变化的部分,而不会影响到应用的其它部分。提高了应用的弹性与可维护性。

策略模式中的一系列算法,就是应用中会变化的部分被一个个封装起来。如策略模式类图中具体算法实现ConcreteStrategyA、ConcreteStrategyB、ConcreteStrategyC,如果需要对某一个算法如ConcreteStrategyA进行改正,只需要对其一个实现类进行修改即可,不会对其它类产生影响;或者需要添加新的算法实现,只需要新增一个实现即可不会对旧的代码产生影响。

3)使它们可相互替换,蕴含着面向对象设计原则--针对接口编程。

OO设计原则:针对接口编程,而不是针对实现编程。

针对接口编程的真正意思是针对超类型编程。更具体的说变量的声明类型应该是超类型,通常是一个抽象类型或一个接口,如此只要是具体实现此超类型的实现类所产生的对象都可以指定给这个变量;也意味着,声明类时不用理会执行时真正的对象类型。

如策略模式类图中,Context声明类型为超类型Strategy,Context不需要理会执行时具体的对象类型是哪一个;同时,运行时也可以对具体的对象类型进行修改。

第二篇:以案例-鸭子游戏对策略模式解析

引自《Head First 设计模式》-- 进入设计模式的世界。

1)原始需求:现有一款游戏,游戏中出现各种鸭子,一边游泳,一边呱呱叫。原始设计:采用面向对象技术,设计一个鸭子(Duck)超类,并让各种鸭子继承此超类。如下图所示:

2)需求变更1:现在我们得让鸭子能够飞。这是公司管理层为了更高的市场份额制定的方案(作为程序员的你不得不对游戏进行升级)。

我们继续使用继承的方式实现此需求,在超类中添加飞行方法(fly),如下图所示:

通过在超类中添加方法,所有的子类都会继承它,改动非常小,确能够实现在所有子类中复用。

3)问题发生了?在一次产品演示会上,有一只橡皮鸭在屏幕上飞来飞去......

橡皮鸭是模型鸭子并不能够飞行,但超类中实现了飞行方法,使得橡皮鸭这个子类同样也具备了飞行的方法,如下图所示:

为了解决这个问题,我们不得不在子类橡皮鸭中重写飞行方法(fly)以覆盖超类中的飞行方法,但是如果又有新的鸭子子类也不能飞行,那不得不对每个不能飞行的鸭子子类进行重写。

总结:使用继承带来的缺点,1.代码在多个子类中复用,2.运行时的行为不易改变(在编译期就已经确定好),3.难以得到子类鸭子的全部行为,4.超类改变牵一发动全身。

4)试着使用接口的方式解决?把飞行行为、叫声行为抽象成接口,能够飞的子类鸭子实现飞行接口,不能够飞行的就不实现飞行接口。如下图所示:

采用接口的方式,使用继承因超类改变而使得所有子类都会受影响的问题得到解决,但又产生了新的问题,每一个子类都不得不编写飞行方法,当子类数量变得很大时, 将会造成大量的重复代码;而且当需要对飞行方法进行很小的修改时,不得不对每一个子类的飞行方法进行修改,这将是另一场灾难。

5)OO原则:封装变化。把鸭子游戏中会变化的部分抽取出来,如鸭子的飞行行为与叫声行为,如下图所示:

这样鸭子类就不需要知道飞行行为、叫声行为的具体实现细节了。

OO原则--封装变化:把会变化的部分抽取出并封装起来,以便以后可以轻易的扩展此部分,而不影响其它部分。这样系统变得更有弹性。

6)OO原则:针对接口编程。利用接口代表每个行为,每个行为有自己不同的实现类。如下图所示:

这样设计后,鸭子类不再负责实现飞行方法fly()和叫声方法quack(),而是由行为类专门负责实现。使得飞行行为、叫声行为不再会绑死在鸭子类中,同时这些行为类也能非常方便的复用到其它地方。

7)OO原则:多用组合,少用继承。现在我们整合鸭子类,将飞行和呱呱叫行为,委托给具体的行为类处理,如下图所示:

使用组合建立的系统具有很大的弹性,且可以运行时改变行为。鸭子游戏重构后如下图所示:

鸭子游戏中的飞行行为、呱呱叫行为其实就是使用的策略模式。如呱呱叫、吱吱叫等就是一系列算法,它们共有的特性都是叫声行为,不同的叫声行为之间可相互替换,它们的变化独立于使用它们的客户鸭子类。

第三篇 案例练习,案例引自网络。

案例代码链接详见gitHub:

https://github.com/chentian114/100-dayaction/tree/master/designpattern-1/src/main/java/com/chen/dayaction/designpattern/strategy1

案例1:流量冲值案例,根据客户选择不同的产品,选择相应的冲值渠道进行流量冲值,流量冲值渠道有(麻袋氪、融漫、极信)。

具体实现参考链接 FlowRecharge

案例2:出行方式案例,根据不同天气选择不同的出行方式:晴天选择骑行、阴天选择步行、雨天选择开小车。

具体实现参考链接 GoWay

案例3:士兵射击游戏,士兵可以选择不同的枪支进行射击,如步枪、手枪。

具体实现参考链接 SoldierGame:

案例4:诸葛亮的三个锦囊妙计,刘备到江东娶孙尚香,三个计策分别在三种不同情况下使用:刚到江东,使用找乔国老开后门计策;结婚后,使用找吴国太开绿灯计策;逃离江东情况下,使用找孙夫人断后计策。

具体实现参考链接 Stratagem:

案例5:策略枚举案例,实现输入两个数字与加减操作符获得计算结果。

具体实现参考链接CalcualtorDemo

第四篇 总结

三条面向对象设计原则:1、封装变化 2、针对接口编程,而不是实现编程3、多用组全,少用继承。

策略模式:定义一个算法族,一个个封装起来,使它们可相互替换。使用算法的变化独立于使用它的客户。

优点:

算法可以自由切换,扩展性良好。

缺点:

策略类数量增多,所有策略类都需要暴露给客户,增加客户的难度。

适用场景:

1、当需要频繁的增加else if或case时,可以考虑使用策略模式减少它们之间的耦合度。

2、多个类只有在算法或行为上稍有不同的场景。

3、算法需要自由切换的场景。

4、需要屏蔽算法规则的场景。

设计模式1-策略模式全面解析+案例实践+总结相关推荐

  1. Java设计模式之策略模式与状态模式

    一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...

  2. python策略模式包含角色_详解Python设计模式之策略模式

    虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用.<设计模式:可复用面向对象软件的基础>一书中有 23 个模式,其中有 16 个在动态语言中"不见了,或者简 ...

  3. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索"为什么MVC不是一种设计模式呢?"其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composi ...

  4. Java设计模式之策略模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  5. 橘子学设计模式之策略模式

    策略模式 1.简介 俗话说:条条大路通罗马.在很多情况下,实现某个目标的途径不止一条,例如我们在外出 旅游时可以选择多种不同的出行方式,如骑自行车.坐汽车.坐火车或者坐飞机,可根据实 际情况(目的地. ...

  6. 设计模式之策略模式+工厂模式+模板模式结合

    设计模式之策略模式+模板模式 为什么总是学不好设计模式 从"登录功能"中发现问题. 首先我们简单的了解功能需求: 于是你开始干活了: 1.控制层代码如下,根据不同的登录方式调用不同 ...

  7. 设计模式之策略模式详解

    设计模式之策略模式详解 概述 先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车.可以坐汽车.可以坐火车.可以坐飞机. 作为一个程序猿,开发需要选择一款开发工具,当然可以进行代码开发的工具有 ...

  8. JAVA架构师之路十五:设计模式之策略模式

    JAVA架构师之路十四:设计模式之模板模式 策略模式 1. 策略模式 2. 优惠券案例 3. 支付案例 人生的游戏不在于拿了一副好牌,而在于怎样去打好坏牌,世上没有常胜将军,勇于超越自我者才能得到最后 ...

  9. Head First设计模式之策略模式(Strategy)

    小白将从以下几点对策略模式进行解析 策略模式引入的设计技巧 策略模式的定义及类图 策略模式的优缺点 策略模式的应用场景 策略模式实战 总结 零.策略模式引入的技巧 先过一遍,放入脑海中,等看完后面所有 ...

最新文章

  1. mysql去重保留最后一个_MySQL-去重留一
  2. 微服务并不能解决你的烂代码问题
  3. 调制的缺点_电光调制与声光调制原理和应用领域
  4. python读取excel文件-Python 读写excel文件
  5. 与善淘网一起做慈善商店
  6. Sublime text3 代码格式化插件vue
  7. python语音识别框架_横评:五款免费开源的语音识别工具
  8. 涂抹果酱_如何玩果酱
  9. MySQL事务隔离级别及场景测试
  10. ASP.NET异常全记录-----回发或回调参数无效
  11. 动态参数 maven_Spring Security 动态url权限控制(三)
  12. 宝可梦世界无限极可以玩服务器吗,口袋妖怪世界无极限运行库
  13. 陕西师范大学计算机专业排名,陕西师范大学优势专业排名,2021年陕西师范大学最好的专业排名...
  14. 一个函数中写多少行代码比较合适呢?
  15. 宗地图绘制要求和规范_国内土地市场宗地图的绘制标准制图规范-【领仕网】...
  16. OpenPose安装(gtx1650+cuda10.1+cudnn7.6.0+anaconda3)
  17. Word页面视图下不显示内容但web视图下可以显示的问题
  18. 现在的国产深度deepin操作系统不赖,推荐试用
  19. RTX 2013安装破解文档
  20. 苹果服务器系统状态查询网站,mac电脑服务器地址怎么查看

热门文章

  1. html5 canvas通过javascript绘制漂亮的时钟
  2. Maxtang 大唐J6412四网口迷你主机安装NAS黑群晖教程
  3. 荣耀linux电脑怎么安装windows,荣耀笔记本不会安装 Win10 系统 只需这六步即可完美安装...
  4. win10 配置防火墙策略
  5. hadoop的分区、分组
  6. 2009年12月23日
  7. 1053.枚举型习题(1):输入整数输出其对应的颜色
  8. 游戏运维及运营存在问题
  9. vpython 做圆周运动_《每周一点canvas动画》——圆周运动
  10. discuz QQ互联