在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

大话设计模式中程杰老师给出的定义是这样的:策略模式(Strategy),定义了算法家族,分别封装起来,让它们之间可以互相替换,从模式让算法的变化不会影响到使用算法的用户

面向对象编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类,即区分这些类的只是他们的直接行为;

一个很形象的实例就是商场的收银系统,商场收银时如何促销,用打折还是返利,其实都是一些算法,打一折和打九折只是形式不同,抽象分析出来,所有的打折算法都是一样的,算法本身只是一种实现促销或打折的策略,重要的是这些算法是随时都可能被替换掉的,这就是变化点,而封装变化点是我们面向对象的一种很重要的思维方式。

实例解析

我们将创建一个定义活动的 Strategy 接口和实现了 Strategy 接口的实体策略类。Context 是一个使用了某种策略的类。
StrategyPatternDemo,我们的演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化。类图如下:

策略接口:

package com.dfcDemo;public interface Strategy {public int doOperation(int num1,int num2);}

四个策略实现类:

package com.dfcDemo;public class StrategySubstract implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;}}
package com.dfcDemo;public class StrategyAdd implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}}
package com.dfcDemo;public class StrategyMulpitly implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 * num2;}}
package com.dfcDemo;public class StrategyDivision implements Strategy{@Overridepublic int doOperation(int num1, int num2) {//此处注重策略模式的应用,只给出简单实现,不考虑除数为0的情况return num1 / num2;}}

使用策略的Context类:

package com.dfcDemo;public class Context {private Strategy strategy;public Context(Strategy strategy){this.strategy = strategy;}public int executeStrategy(int num1,int num2){return strategy.doOperation(num1, num2);}
}

测试类:

package com.dfcDemo;public class TestStrategyDemo {public static void main(String[] args) {Context contextAdd = new Context(new StrategyAdd());System.out.println("6 + 3 = " + contextAdd.executeStrategy(6, 3));Context contextSubstract = new Context(new StrategySubstract());System.out.println("6 - 3 = " + contextSubstract.executeStrategy(6, 3));Context contextMulpitly = new Context(new StrategyMulpitly());System.out.println("6 * 3 = " + contextMulpitly.executeStrategy(6, 3));Context contextDivision = new Context(new StrategyDivision());System.out.println("6 / 3 = " + contextDivision.executeStrategy(6, 3));}}
运行结果:6 + 3 = 9
6 - 3 = 3
6 * 3 = 18
6 / 3 = 2

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。Strategy类层次为Context定义了一系列的可供重用的算法和行为。当不同的行为堆砌在一个类中的时候,就很难避免使用条件语句来判断选择合适的行为,将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。

优点:

1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好。
4、简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。

使用场景:

1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。
3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

策略模式时用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种可能发生的变化。

但是在策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式使用对象,这本身并没有解除客户端需要选择判断的压力,解决这一问题的方法是使用策略模式和简单工厂模式结合,选择具体实现的职责也由策略使用类Context来承担。这就最大化的减轻了客户端的职责。

策略模式和简单工厂模式结合:

改造使用策略模式的Context类使其实现一个简单工厂的功能

package com.dfcDemo;//将实例化具体策略的过程由客户端转移到具体策略使用类ContextFactory中
public class ContextFactory {private Strategy strategy;//注意这里传入的参数是一个表示策略类型的字符串,而不是具体的策略对象public ContextFactory(String type){switch(type){case "add":StrategyAdd add = new StrategyAdd();strategy = add;break;case "substract":StrategySubstract substract = new StrategySubstract();strategy = substract;break;case "multiply":StrategyMulpitly mulpitly = new StrategyMulpitly();strategy = mulpitly;break;case "division":StrategyDivision division = new StrategyDivision();strategy = division;break;}}public int executeStrategy(int num1,int num2){return strategy.doOperation(num1, num2);}
}
//测试方法
public int TestStrategyFactoryDemo(String type) {ContextFactory contextFactory = new ContextFactory(type);return contextFactory.executeStrategy(6, 3);}

这样具体策略的使用就与客户端彻底分离了。

大话设计模式—策略模式相关推荐

  1. 大话设计模式——策略模式

    1)商场收银系统 import java.awt.event.ActionEvent; import java.awt.event.ActionListener;import javax.swing. ...

  2. 大话设计模式-策略模式与简单工厂模式

    来源:http://blog.csdn.net/wulingmin21/article/details/6712684 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策 ...

  3. 大话设计模式策略模式_多种方法实现商场促销

    V1.0面向过程设计思想 V1.1 添加计费方式下拉框,发现程序不容易维护,不容易扩展,更不容易复用 采用面向对象的设计思想 V2.0面向对象+简单工厂 缺点是每次维护或扩展收费方式都要改动这个工厂, ...

  4. linkin大话设计模式--常用模式总结

    linkin大话设计模式--常用模式总结 一,常用设计模式定义 Abstract Factory(抽象工厂模式):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. Adapter( ...

  5. Python设计模式-策略模式

    Python设计模式-策略模式 代码基于3.5.2,代码如下; #coding:utf-8 #策略模式class sendInterface():def send(self,value):raise ...

  6. 关于设计模式——策略模式-Strategy Pattern

    文章目录 1 策略模式 1.1 模拟鸭子 1.2 设计原则 1.3 整合行为 1.4 模拟鸭子代码的代码 1.5 动态设定行为 1.6 重新查看整体 1.7 继承和组合 1.8 总结 1.9 优劣期间 ...

  7. [设计模式] ------ 策略模式

    策略模式 它定义了算法家族,分别封装起来,让他们直接可以互相替换,此模式让算法的变化,不会影响到使用算法的客户 其实很简单,可能很多人都用到了,只不过还不知道这就是策略模式而已. 比如定义一个接口A, ...

  8. java 策略模式 促销_java设计模式——策略模式

    一. 定义与类型 定义:针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是它们可以相互替换.策略模式的最大特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能.当代码中 ...

  9. Springboot 使用设计模式- 策略模式

    前言 直白点,什么场景我们需要使用到设计模式- 策略模式. 在平常的springboot项目里面做CRUD,我们的习惯性基本是 一个mapper,一个service,一个serviceImpl. 但是 ...

最新文章

  1. leetcode算法题--骑士在棋盘上的概率★
  2. 内存管理 初始化(七)kmem_cache_init_late 初始化slab分配器(下)
  3. CDN加速服务有什么功能和作用?
  4. java 实验报告模板_Java实验报告模板.doc.doc
  5. NE5532前级音调板 带高中低音调节和音量调节
  6. SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行)
  7. LeetCode 696. 计数二进制子串
  8. nginx介绍(一) 简介篇
  9. 让这家有12万名员工、1.7万种产品的钢铁厂平滑上云的黑科技是什么?
  10. Spark基础学习笔记19:RDD的依赖与Stage划分
  11. 3C(Computer、Communication、Consumer Electronic)
  12. java 文件删除不了
  13. Python之XML模块
  14. 精品思维导图模板合集,锻炼你的逻辑思维,提升能力空间
  15. 最新2019年dnf辅助制作视频教程
  16. java mysql点赞功能_怎么实现一个点赞功能?
  17. 套接字I/O模型-WSAEventSelect(转载)
  18. 数据结构 day07 基础知识学习 (二叉树 的 前中后遍历 ,插入节点,删除叶子节点, 二叉树的节点个数 )
  19. Spring boot 项目 执行 jar 包时 显示 没有主清单属性
  20. 软件测试中测试版本的质量状况,测试结果分析和质量报告

热门文章

  1. zend server 配置问题 ZendEnablerConf.xml
  2. 一个应用程序多线程误用的分析
  3. myeclipse 自动生成注释
  4. android try catch并不影响性能
  5. Android Studio: Debug Android SDK Source Code
  6. Android 高级Drawable资源---复合Drawable----状态列表Drawable
  7. 服务端监控要怎么做?
  8. c++学习笔记之运算符重载
  9. 查询数据表结构并查出结构的结构信息
  10. vue通信的N种方式