文章目录

  • 1. 引入策略模式
  • 2. 策略模式定义
  • 3. 策略模式的优点

1. 引入策略模式

智谋无敌的诸葛亮,在刘备去东吴招亲之前,特授以伴郎赵云三个锦囊,说是按天机拆开解决棘手问题。

这三个妙计分别是:找乔国老帮忙(也就是走后门了),求吴国太放行(诉苦)以及孙夫人断后,想想看,这三个计谋有什么相似之处,他们都是告诉赵云要怎么执行,也就是说这三个计谋都有一个方法是执行,具体执行什么内容,每个计谋当然不同了,分析到这里,我们是不是就有这样一个设计思路:三个妙计应该实现的是同一个接口?

接口很简单,定义了一个方法operate,每个妙计都是可执行的:

public interface IStrategy {/*** 每个锦囊都是一个可执行的算法*/public void operate();
}

第一个妙计是找乔国老开后门:

public class BackDoor implements IStrategy{@Overridepublic void operate() {System.out.println("找乔国老帮忙,让吴国给孙权施加压力");}
}

第二个妙计是找吴国太哭诉,企图给自己开绿灯:

public class GivenGreenLight implements IStrategy{@Overridepublic void operate() {System.out.println("找吴国太开路灯,放行!");}
}

第三个妙计是在逃跑的时候,让新娘子孙夫人断后,谁来砍谁:

public class BlockEnemy implements IStrategy{@Overridepublic void operate() {System.out.println("孙夫人断后,挡住追兵");}
}

在这个场景中,三个妙计都有了,那还缺少两个配角:第一,妙计肯定要放到一个地方吧,这么重要的东西要保管呀,也就是承装妙计的锦囊,所以俗称锦囊妙计嘛;第二,这些妙计都要有一个执行人吧,是谁?当然是赵云了,妙计是小亮给的,执行者是赵云。赵云就是一个干活的人,从锦囊中取出妙计,执行,然后获胜。过程非常清晰,我们把完整的过程设计出来。

在类图中增加了一个Context封装类(也就是锦囊),其作用是承装三个策略,方便赵云使用,我们来看Context代码:

public class Context {private IStrategy strategy;/*** 构造函数,你要使用哪个妙计*/public Context(IStrategy strategy){this.strategy = strategy;}/*** 使用计谋,看我出招了*/public void operate(){this.strategy.operate();}
}

通过构造函数把策略传递进来,然后用operate()方法来执行相关的策略方法。三个妙计有了,锦囊也有了,然后就是赵云雄赳赳地揣着三个锦囊:

public class ZhaoYun {//赵云出场了,他根据诸葛亮给他的交代,依次拆开妙计public static void main(String[] args) {Context context;System.out.println("---刚刚到吴国的时候拆第一个---");//拿到妙计context = new Context(new BackDoor());//拆开执context.operate();System.out.println("---刘备乐不思蜀了,拆第二个了---");context = new Context(new GivenGreenLight());context.operate();System.out.println("---孙权的小兵追来了,咋办?拆第三个---");context = new Context(new BlockEnemy());context.operate();}
}

—刚刚到吴国的时候拆第一个—
找乔国老帮忙,让吴国给孙权施加压力
—刘备乐不思蜀了,拆第二个了—
找吴国太开路灯,放行!
—孙权的小兵追来了,咋办?拆第三个—
孙夫人断后,挡住追兵

2. 策略模式定义

策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(Policy Pattern)。其定义如下:
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。

这个定义是非常明确、清晰的,“定义一组算法”,看看我们的三个计谋是不是三个算法?“将每个算法都封装起来”,封装类Context不就是这个作用吗?“使它们可以互换”当然可以互换了,都实现是相同的接口,那当然可以相互转化了。

策略模式的通用类图:

  • Context封装角色:它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,
    封装可能存在的变化
  • Strategy抽象策略角色:策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
  • ConcreteStrategy具体策略角色:实现抽象策略中的操作,该类含有具体的算法。

策略模式的通用源码:

抽象策略角色,它是一个非常普通的接口,定义一个或多个具体的算法:

public interface Strategy {/*** 策略模式的运算法则*/public void doSomething();
}

具体策略也是非常普通的一个实现类,只要实现接口中的方法就可以:

public class ConcreteStrategy1 implements Strategy{@Overridepublic void doSomething() {System.out.println("具体策略1的运算法则");}
}
public class ConcreteStrategy2 implements Strategy{@Overridepublic void doSomething() {System.out.println("具体策略2的运算法则");}
}

策略模式的重点就是封装角色,它是借用了代理模式的思路,大家可以想想,它和代理模式有什么差别,差别就是策略模式的封装角色和被封装的策略类不用是同一个接口,如果是同一个接口那就成为了代理模式。我们来看封装角色:

public class Context {// 抽象策略private Strategy strategy;/*** 构造函数设置具体策略* @param strategy*/public Context(Strategy strategy){this.strategy = strategy;}/*** 封装后的策略方法*/public void doAnything(){this.strategy.doSomething();}
}

高层模块的调用非常简单,知道要用哪个策略,产生出它的对象,然后放到封装角色中就完成任务了:

public class Client {public static void main(String[] args) {// 声明一个具体的策略Strategy strategy = new ConcreteStrategy1();// 声明上下文对象Context context = new Context(strategy);// 执行封装后的方法context.doAnything();}
}

3. 策略模式的优点

  • 算法可以自由切换:这是策略模式本身定义的,只要实现抽象策略,它就成为策略家族的一个成员,通过封
    装角色对其进行封装,保证对外提供“可自由切换”的策略。
  • 避免使用多重条件判断:如果没有策略模式,我们想想看会是什么样子?一个策略家族有5个策略算法,一会要使用A策略,一会要使用B策略,怎么设计呢?使用多重的条件语句?多重条件语句不易维护,而且出错的概率大大增强。使用策略模式后,可以由其他模块决定采用何种策略,策略家族对外提供的访问接口就是封装类,简化了操作,同时避免了条件语句判断。
  • 扩展性良好:这甚至都不用说是它的优点,因为它太明显了。在现有的系统中增加一个策略太容易了,只要实现接口就可以了,其他都不用修改,类似于一个可反复拆卸的插件,这大大地符合了OCP原则。

读书 | 设计模式之禅 - 策略模式相关推荐

  1. 设计模式之禅-策略模式

    1 策略模式有点类似状态模式,不过策略的调用链切换是固定的. A  A can not do -> B B can not do -> C do 2 代码 #include <ios ...

  2. 读设计模式之禅--策略模式

    定义:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换. package design.Strategy;/*** @Author: hyh* @Date: 2021/8/19 14:04* ...

  3. 设计模式之禅——策略模式(Strategy Pattern)

    1.基本概念 在策略模式中,一个类的行为或算法可以在运行时更改.我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象.策略对象改变 context 对象的执行算法. 2. ...

  4. 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

    设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...

  5. 设计模式入门(策略模式)

    [0]README 0.1)本文部分文字描述转自 "head first 设计模式",旨在学习 设计模式入门(策略模式) 的基础知识: 0.2)本文章节4和5的source cod ...

  6. Head First Design Mode(2)-设计模式入门(策略模式)

    该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动! 设计模式入门: 欢迎来到设计模式世界: 我们会看到设计模式的用途和优点,再看看关键的OO原则,通过实例来了解模式是如何运作的 ...

  7. 【设计模式七之策略模式】你有你的张良计,我有我的过墙梯

    Strategy模式 细说策略模式 策略模式究竟是什么模式 策略模式的场景 官宣的策略模式 代码展示 代码一 细说策略模式 提示: 博主:章飞 _906285288的博客 博客地址:http://bl ...

  8. 设计模式 之美 -- 策略模式

    策略模式作为行为型设计模式中的一种,主要封装相同功能的不同实现算法,用于在用户程序内部灵活切换.对用户来说能够快速替换对应的算法,能够让算法的实现独立于使用的用户. 基本的UML类图如下: 用户使用S ...

  9. Java设计模式之十一 ---- 策略模式和模板方法模式

    前言 在上一篇中我们学习了行为型模式的访问者模式(Visitor Pattern)和中介者模式(Mediator Pattern).本篇则来学习下行为型模式的两个模式,策略模式(Strategy Pa ...

最新文章

  1. Linux环境编程--进程通信
  2. 【青少年编程】陈晓光:打靶游戏
  3. Web:你知道我这十几年是怎么过来的吗?!
  4. ASP.NET MVC 使用Swagger需要注意的问题!!!
  5. mysql 子查询模糊匹配_sql中的查询(模糊查询,子查询,联表查询)
  6. VS2010与OpenCV2410简单配置
  7. select时尽可能少使用as对性能很有好处
  8. Python基础与大数据应用(三)
  9. 技术到管理岗位的角色转换:从优秀骨干到优秀管理者
  10. 程序员-IT领域的魔法师
  11. Wps日期时间格式转文本、科学计数法转数字
  12. Markdown 学习入门
  13. 2022.08.10 第三组 高小涵
  14. ubuntu ffmpeg 截取视频指定时间范围,坐标范围
  15. 【SQL注入-13】利用SQL注入漏洞读写文件案例
  16. 所谓的日常 #8 - 王司徒巧使連環計 董太師大鬧鳳儀亭
  17. u盘乱码怎么办?看他怎么恢复的(不花一分钱)
  18. 1.Anaconda Navigator更新_Anaconda详细教程
  19. CCTV 2006 感动中国人物揭晓
  20. 视频水印如何去除?保存的视频怎么去水印?

热门文章

  1. 线程和进程的小结(未完待续)
  2. ANDORID~支持的设备
  3. Prometheus 存储层的演进
  4. 照片heic怎么转成jpg?
  5. MATLAB常用技巧之复数判断,矩阵中空值判断,空矩阵判断
  6. 远程办公18年,把一个开源工具变成了价值 75亿美元的跨国企业
  7. android网络请求框架汇总
  8. websocket autobahn webrtc
  9. ie下ajax请求不到数据库,解决IE下Ajax请求无效
  10. 【FIW2022精彩回顾】国泰君安新一代核心交易系统网络底座建设实践