意图

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

动机

策略模式为了适应不同的需求,只把变化点封装了,这个变化点就是实现不同需求的算法,但是,用户需要知道各种算法的具体情况。就像上面的加班工资,不同的加班情况,有不同的算法。我们不能在程序中将计算工资的算法进行硬编码,而是能自由的变化的。这就是策略模式。

刚刚加班回来;哎,公司规定平时加班只有10块钱的餐补;星期六和星期天加班,只给串休假;在国家规定的节假日按照3倍工资发放。那么对于这么多的计算加班费的方法,公司的OA系统是如何进行做的呢?各种计算加班费的情况就可以认为是策略模式

适用性

  • 许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
  • 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式
  • 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
  • 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

结构

参与者

Strategy:定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法;
ConcreteStrategy:实现Strategy接口的具体算法;
Context:使用一个ConcreteStrategy对象来配置;维护一个对Stategy对象的引用,同时,可以定义一个接口来让Stategy访问它的数据。

效果

相关算法系列Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。

实现

纯策略模式,实际上就是父类为纯虚函数,子类根据需求实现各种方法

 1 #include <iostream>
 2 using namespace std;
 3
 4 // The abstract strategy
 5 class Strategy
 6 {
 7 public:
 8      virtual void AlgorithmInterface() = 0;
 9 };
10
11 class ConcreteStrategyA : public Strategy
12 {
13 public:
14      void AlgorithmInterface()
15      {
16           cout<<"I am from ConcreteStrategyA."<<endl;
17      }
18 };
19
20 class ConcreteStrategyB : public Strategy
21 {
22 public:
23      void AlgorithmInterface()
24      {
25           cout<<"I am from ConcreteStrategyB."<<endl;
26      }
27 };
28
29 class ConcreteStrategyC : public Strategy
30 {
31 public:
32      void AlgorithmInterface()
33      {
34           cout<<"I am from ConcreteStrategyC."<<endl;
35      }
36 };
37
38 class Context
39 {
40 public:
41      Context(Strategy *pStrategyArg) : pStrategy(pStrategyArg)
42      {
43      }
44      void ContextInterface()
45      {
46           pStrategy->AlgorithmInterface();
47      }
48 private:
49      Strategy *pStrategy;
50 };
51
52 int main()
53 {
54      // Create the Strategy
55      Strategy *pStrategyA = new ConcreteStrategyA;
56      Strategy *pStrategyB = new ConcreteStrategyB;
57      Strategy *pStrategyC = new ConcreteStrategyC;
58      Context *pContextA = new Context(pStrategyA);
59      Context *pContextB = new Context(pStrategyB);
60      Context *pContextC = new Context(pStrategyC);
61      pContextA->ContextInterface();
62      pContextB->ContextInterface();
63      pContextC->ContextInterface();
64
65      if (pStrategyA) delete pStrategyA;
66      if (pStrategyB) delete pStrategyB;
67      if (pStrategyC) delete pStrategyC;
68
69      if (pContextA) delete pContextA;
70      if (pContextB) delete pContextB;
71      if (pContextC) delete pContextC;
72 }

在实际操作的过程中,我们会发现,在main函数中,也就是在客户端使用策略模式时,会创建非常多的Strategy,而这样就莫名的增加了客户端的压力,让客户端的复杂度陡然增加了。那么,我们就可以借鉴简单工厂模式,使策略模式和简单工厂模式相结合,从而减轻客户端的压力,代码实现如下:

  1 #include <iostream>
  2 using namespace std;
  3
  4 // Define the strategy type
  5 typedef enum StrategyType
  6 {
  7     StrategyA,
  8     StrategyB,
  9     StrategyC
 10 }STRATEGYTYPE;
 11
 12 // The abstract strategy
 13 class Strategy
 14 {
 15 public:
 16     virtual void AlgorithmInterface() = 0;
 17     virtual ~Strategy() = 0; // 谢谢hellowei提出的bug,具体可以参见评论
 18 };
 19
 20 Strategy::~Strategy()
 21 {}
 22
 23 class ConcreteStrategyA : public Strategy
 24 {
 25 public:
 26     void AlgorithmInterface()
 27     {
 28         cout << "I am from ConcreteStrategyA." << endl;
 29     }
 30
 31     ~ConcreteStrategyA(){}
 32 };
 33
 34 class ConcreteStrategyB : public Strategy
 35 {
 36 public:
 37     void AlgorithmInterface()
 38     {
 39         cout << "I am from ConcreteStrategyB." << endl;
 40     }
 41
 42     ~ConcreteStrategyB(){}
 43 };
 44
 45 class ConcreteStrategyC : public Strategy
 46 {
 47 public:
 48     void AlgorithmInterface()
 49     {
 50         cout << "I am from ConcreteStrategyC." << endl;
 51     }
 52
 53     ~ConcreteStrategyC(){}
 54 };
 55
 56 class Context
 57 {
 58 public:
 59     Context(STRATEGYTYPE strategyType)
 60     {
 61         switch (strategyType)
 62         {
 63         case StrategyA:
 64             pStrategy = new ConcreteStrategyA;
 65             break;
 66
 67         case StrategyB:
 68             pStrategy = new ConcreteStrategyB;
 69             break;
 70
 71         case StrategyC:
 72             pStrategy = new ConcreteStrategyC;
 73             break;
 74
 75         default:
 76             break;
 77         }
 78     }
 79
 80     ~Context()
 81     {
 82         if (pStrategy) delete pStrategy;
 83     }
 84
 85     void ContextInterface()
 86     {
 87         if (pStrategy)
 88             pStrategy->AlgorithmInterface();
 89     }
 90
 91 private:
 92     Strategy *pStrategy;
 93 };
 94
 95 int main()
 96 {
 97     Context *pContext = new Context(StrategyA);
 98     pContext->ContextInterface();
 99
100     if (pContext) delete pContext;
101 }

转载于:https://www.cnblogs.com/raichen/p/5673575.html

Strategy 策略模式相关推荐

  1. Java的设计模式----strategy(策略模式)

    设计模式: 一个程序员对设计模式的理解: "不懂"为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的"复杂"恰恰就是设计模式的精 ...

  2. 设计模式——Strategy(策略)模式

    目录 前言 1 定义 2 适用性 3 结构 3.1 结构图 3.2 参与者 4 实际应用举例 4.1 Context--List列表和StuContext 4.2 具体策略:ConcreteStrat ...

  3. [设计模式] —— Strategy 策略模式

    文章目录 Strategy 策略模式 动机 定义 示例代码 结构图 总结 Strategy 策略模式 组件协作模式通过晚绑定,来实现框架与应用程序之间的松耦合.是框架和引用程序协作常用的. 动机 某些 ...

  4. 【设计模式】2.Strategy 策略模式

    Strategy 策略模式 动机(Motivation) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持不使用的算法也 ...

  5. 设计模式之Strategy策略模式

    文章目录 前言 一.Strategy策略模式 二.策略模式原则 三.使用场景 1.先做比较练习 2.为一组对象排序 3.使用Lambda表达式的方式 前言 本人对于设计模式的学习,仅供参考! 一.St ...

  6. Strategy策略模式

    策略模式定义了一系列算法,把它们一个个封装起来,并且使它们可相互替换.该模式可使得算法能独立于使用它的客户而变化.Strategy模式是行为模式,正因为他是一种行为模式,所以他不是用来解决类的实例化的 ...

  7. 设计模式学习笔记--Strategy 策略模式

    所谓策略模式(Strategy Pattern),就是将策略 (算法) 封装为一个对象,易于相互替换,如同 USB 设备一样可即插即用:如果将策略.具体的算法和行为,编码在某个类或客户程序内部,将导至 ...

  8. 步步为营 .NET 设计模式学习笔记 三、Strategy(策略模式)

    策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.(原文:The Strategy Pattern defines a fami ...

  9. 12种行为模式 之2 STRATEGY 策略模式

    [b]策略模式的组成[/b] 1):抽象策略角色: 通常由一个接口或者抽象类实现. 2):具体策略角色:包装了相关的算法和行为. 3):环境角色:持有一个策略类的引用,最终给客户端(上层模块)调用. ...

最新文章

  1. Python 骚操作:微信远程控制电脑
  2. android广告页白屏_android 白屏
  3. SAP Spartacus not found的页面处理机制
  4. java发送邮件354_基于SMTP的JAVA邮件发送程序
  5. c# 整数除法取整_Java 如何取整整数除法的结果?
  6. jar命令成功完成 java -jar 命令却提示“没有主清单属性”!
  7. 虚拟化安全怎么做?靠安全设备虚拟化还是换个思路?
  8. 苹果笔记本硬盘怎么解锁_笔记本如何加装内存、硬盘,怎么增大C盘容量
  9. PIO(编程输入/输出模型)和DAM(直接访问内存)
  10. 数学之美 第六章——信息的度量和作用
  11. 好看的皮囊 · 也是大自然的杰作 · 全球高质量 · 美图 · 集中营 · 美女 · 2017-08-29期...
  12. POI导出word单元格合并
  13. 修复ASUS in WinRE教程
  14. ios9遇到 App Transport Security has blocked a cleartext HTTP(http://) resource load 错误
  15. FT232芯片的国产化替代
  16. uniwide服务器不能进入系统,AMD四核心K10 Opteron处理器下月底出货
  17. python怎么处理中英文符号网名_英文带符号的网名_英文网名带符号加中文
  18. 三分钟,我让搞后端的学弟爱上了Eolink
  19. oracle 数据库密码生产同步模拟环境 ,随记常用命令
  20. 吃透Java基础一:Java访问权限修饰符

热门文章

  1. 【ZOJ - 2949】Coins of Luck (概率dp,期望)
  2. java 跨域上传_java后台图片跨域上传图片 文件
  3. c语言bfs程序讲解,面试算法--二叉树DFS/BFS实现(C语言)
  4. Linux学习:第三章-Linux常用命令-1
  5. 金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-(一千零一拾一元整)输出。...
  6. 微信端php 开发技术要求,微信第三方平台开发详解——PHP版
  7. Python(5)-注释
  8. 《Python Cookbook 3rd》笔记(4.7):迭代器切片
  9. 《Python Cookbook 3rd》笔记(2.17):在字符串中处理html和xml
  10. 用Tomcat构建一个简单图片服务器