1.定义

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

2.概述

方法是类中最重要的组成部分,一个方法的方法体由一系列语句组成,也就是说一个方法的方法体是一个算法。在某些设计中,一个类的设计人员经常可能设计这样的问题:由于用户需求的变化,导致经常需要修改类中某个方法的方法体,急需要不断地变化算法;
比如,设计Army类(士兵类),该类中有一个int数组,数组元素的值代表士兵的号码,该类中有lineUp()方法,该方法将士兵按它们的号码从小到大排队,类图如下所示:

但是有些部队希望Army创建的对象能够将士兵按照他们的号码从大到小排队或者按照某种方式排序,而不是从小到大。显然Army无法提供这样的对象;
面对这种情况需求,我们只好痛苦地修改lineUp()的方法体,但马上就会发现不行,因为一旦将方法体改变,我们又无法满足以前的业务需求;也许可以在方法中添加多重条件语句,以便根据用户的具体需求决定怎么样排队,但这也不是一个好办法,因为只要一旦有新的需求,就要修改lineUp方法添加判断语句,而且针对某个条件语句的排队代码也可能因该用户的需求变化导致重新编写;
因此,我们采用面向抽象编程来解决该类问题;

3.应用场景

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

4.模式的结构与使用

策略模式的结构中包括三种角色
1.策略(Strategy):策略就是一个接口该接口定义若干个算法标识,即定义了若干个抽象方法;
2.具体策略(ConcreteStrategy):具体策略是实现策略接口的类。具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体实现
3.上下文(Context):上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供一个方法,该方法委托策略变量调用具体策略所实现的策略接口

1.策略模式的UML类图

2.结构的描述

以下通过一个简单的问题来描述策略模式所涉及的各个角色
在某种比赛中有若干个裁判,每位裁判给选手一个得分。选手的最后得分是根据全体裁判的得分计算出来的。请给出集中计算选手得分的评分方法(策略),对于某次比赛,可以从你的方案中选择一种方法作为本次比赛的评分方案。
针对上述问题,使用策略模式设计若干个类。
1.策略
定义了一个策略接口,名字为ComputableStrategy,在里面定义了抽象方法computeScore;

package com.xing.strategy;public interface ComputableStrategy {public abstract double computeScore(double[] a);
}

2.具体策略
对于本问题,有三个具体略:StrategyOne,StrategyTwe,StrategyThree;
具体策略StrategyOne将 double computeScore(double[] a)方法实现为计算数组a的元素的代数平均值,具体代码如下所示:

package com.xing.strategy;public class StrategyOne implements ComputableStrategy{//计算数组a的元素的代数平均值@Overridepublic double computeScore(double[] a) {int sum=0;int score=0;for (double value : a) {sum+=value;}score=sum/a.length;return score;}
}

具体策略StrategyTwe将 double computeScore(double[] a)方法实现为计算数组a的元素的几何平均值,具体代码如下所示:

package com.xing.strategy;public class StrategyTwo implements ComputableStrategy{//计算数组a的元素的几何平均值@Overridepublic double computeScore(double[] a) {double sum=0;double score=0;for (int i = 0; i < a.length; i++) {sum=sum*a[i];}score=Math.pow(sum,1.0/a.length);return score;}
}

具体策略StrategyThree将 double computeScore(double[] a)方法实现为去掉数组a的元素中的一个最大值和一个最小值,然后计算剩余元素的代数平均值,具体代码如下所示:

package com.xing.strategy;
import java.util.Arrays;
public class StrategyThree implements ComputableStrategy{//去掉数组a的元素中的一个最大值和一个最小值,然后计算剩余元素的代数平均值@Overridepublic double computeScore(double[] a) {if(a.length<=2)return 0;double sum=0;double score=0;//对数组进行从小到大排序Arrays.sort(a);for(int i=1;i<a.length-1;i++){sum+=a[i];}score=sum/(a.length-2);return score;}
}

3.上下文
上下文是Gymnastics类,该类包含策略声明的变量,此变量可用于保存具体策略的引用。该类中的getPersonScore(double[] a)方法将委托具体策略的实例计算选手的最后得分,具体代码如下所示:

package com.xing.strategy;
public class Gymnastics {ComputableStrategy computableStrategy;public void setComputableStrategy(ComputableStrategy computableStrategy) {this.computableStrategy = computableStrategy;}public double getPersonScore(double[] a) {if (computableStrategy != null) {return computableStrategy.computeScore(a);} elsereturn 0;}
}

4.主程序测试

package com.xing.strategy;public class Application {public static void main(String[] args) {//创建上下文对象Gymnastics game=new Gymnastics();game.setStrategy(new StrategyOne());//上下文对象使用策略一Person zhang=new Person();zhang.setName("张三");double[] a={9.12,9.25,8.87,9.99,6.99,7.88};Person li=new Person();li.setName("李四");double[] b={9.15,9.26,8.97,9.89,6.97,7.89};zhang.setScore(game.getPersonScore(a));li.setScore(game.getPersonScore(b));System.out.println("使用算术平均值方案:");System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());game.setStrategy(new StrategyTwo());//使用策略二zhang.setScore(game.getPersonScore(a));li.setScore(game.getPersonScore(b));System.out.println("使用几何平均值方案:");System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());game.setStrategy(new StrategyThree());//使用策略三zhang.setScore(game.getPersonScore(a));li.setScore(game.getPersonScore(b));System.out.println("使用(去掉最高,最低)算术平均值方案:");System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());}
}
class Person{String name;double score;public String getName() {return name;}public void setName(String name) {this.name = name;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}
}

5.测试结果展示

5.策略模式的优点。

1.上下文(Context)和具体策略(ConcreteStrategy)是松耦合关系。因此上下文只知道它要使用某一个实现Strategy接口类的实例,但不需要知道具体是哪一个类;
2.策略模式满足开闭原则。当增加新的具体策略时,不需要需求上下文类的代码,上下文就可以引用新的具体策略的实例;

设计模式:(策略模式)相关推荐

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

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

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

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

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

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

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

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

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

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

  6. 李建忠设计模式——策略模式Strategy

    目录 1.策略模式定义 1.动机 2.模式定义 3.结构 2.实现例子 1.问题描述 2.代码实现 3.要点总结 4.参考 1.策略模式定义 1.动机 软件构建过程中,某些对象使用的算法可能多种多样, ...

  7. 15. 星际争霸之php设计模式--策略模式

    题记 ============================================================================== 本php设计模式专辑来源于博客(jy ...

  8. Java设计模式-策略模式作业

    Java设计模式-策略模式作业,所有类和接口均在一个package内 文章目录 前言 一.作业内容 二.具体实现 1.类图 2.Strategy接口 3.PreCopyStrategy类 4.Post ...

  9. 设计模式-策略模式2.0

    设计模式-策略模式2.0 前面文章我们说过了传统的策略模式的实现,本文我们简单说下设计模式中的升级版的策略模式,策略模式2.0. 代码实现 talk is cheap show me the code ...

  10. 设计模式-策略模式(Strategy)-Java

    设计模式-策略模式(Strategy)-Java 目录 文章目录 1.前言 2.示例案例-电影票打折方案 3.策略模式概述 3.1.策略模式定义 3.2.策略模式结构 3.3.策略模式结构图中角色 3 ...

最新文章

  1. MFC 关于new出一个新对话框时,退出对话框内存泄漏的问题解决
  2. c#中将对象序列化为xml(包括list)
  3. C++friend 友元类和友元函数
  4. [蓝桥杯][2014年第五届真题]排列序数(思维)
  5. DataNucleus 3.0与Hibernate 3.5
  6. C++/C中mutalbe与volatile的详解
  7. 02:陶陶摘苹果【一维数组】
  8. html如何判断ie版本,在html中判断IE浏览器的版本
  9. spwm波正弦表生成程序,亲测实用有效!!!!!!速度摘取
  10. C语言根号下ln怎么表示,c语言ln根号x
  11. 极化码 极化现象matlab仿真(信道容量,巴氏参数,高斯近似三种方法)
  12. 求最大李雅普诺夫指数(Largest Lyapunov Exponents,LLE)的 Rosenstein 算法
  13. GIS空间分析(一)——空间分析与GIS
  14. html闹钟设置,设置闹钟标签.html
  15. 波束成形技术原理解析
  16. Codeforces——C. Yet Another Walking Robot
  17. AI识别照片是谁,人脸识别face_recognition开源项目安装使用 | 机器学习
  18. servu ip段访问_西部数码使用指南:利用安全组设置拦截IP(IP段)
  19. ECshop4.1版本搭建
  20. python动态图形_用python生成地球运动的动态模拟动态图

热门文章

  1. ASN.1编码格式介绍
  2. python编程软件下载-Python3.9下载
  3. nmap漏扫工具的使用
  4. Baxter机器人相关配置
  5. Ubuntu 9.10 麦克风无声音解决方法
  6. mysql面试题 学生成绩表_sql面试题(学生表_课程表_成绩表_教师表)
  7. html5 drm,DRM迈入HTML5倒计时:为什么DRM是邪恶的
  8. 【python】sqlalchemy
  9. mysql exec函数_mysql exec 存储过程
  10. java导出文件到excel文件怎么打开_Java导出数据到Excel文件