Strategy 策略模式

意图

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

动机

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

刚刚加班回来;哎,公司规定平时加班只有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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 消息中间件_消息队列中间件 RabbitMQ 详细介绍——安装与基本应用(Python)...

RabbitMQ 是当前最流行的消息中间件(Message Broker)之一&#xff0c;支持多种消息协议(如 AMQP、MQTT)。同时它也是一个轻量级的非常易于部署的开源软件&#xff0c;可以运行在当前大多数操作系统及云端环境中&#xff0c;也能够部署在分布式的集群环境里以达到高可用、可伸缩…

用 Flask 来写个轻博客 (1) — 创建项目

目录 目录前言扩展阅读部署开发环境创建 Github 项目前言 一步一步的实现一个 Flask 轻博客项目启动&#xff0c;最新的代码会上传到 Github。 扩展阅读 欢迎使用 Flask — virtualenv 部署开发环境 连接 GitHubhostnamectl set-hostname flask-dev # 设置 hostname ssh-keyg…

python静态方法,类方法,属性方法,实例方法

DAY 3. 静态方法&#xff0c;类方法&#xff0c;属性方法&#xff0c;实例方法 有四种方法&#xff0c;实例方法&#xff0c;类方法&#xff0c;静态方法&#xff0c;属性方法 实例方法 实例方法的第一个参数是self&#xff0c;他会指向类的实例化对象&#xff0c;只能被对象…

ubuntu 软件包降级

ubuntu 软件包降级 sudo aptitude install libssl-dev 1. 是否接受该解决方案&#xff1f; [Y/n/?] n 2. 是否接受该解决方案&#xff1f; [Y/n/?] y 3. 您要继续吗&#xff1f; [Y/n/?] ysudo aptitude install libcairo21.4.10-1ubuntu4 # 强制降级 sudo aptitude forbid…

java后期发展方向_Java程序员的4个职业发展方向,该如何把握黄金5年?

在Java程序界流行着一种默认的说法叫“黄金5年”&#xff0c;意思是说&#xff0c;一个Java程序员从入职的时候算起&#xff0c;前五年我选择直接影响着整个职业生涯的发展方向和薪资走向。而这5年&#xff0c;也决定了一个程序员能否成为职业大牛的可能。那么&#xff0c;在这…

python 类变量(属性)和实例变量(属性

DAY 4. 类变量&#xff08;属性&#xff09;和实例变量&#xff08;属性&#xff09; 类变量&#xff1a;在所有类的实例之间都可以共享的变量&#xff0c;类变量在所有对象间只保留一份 在类体中定义类的所有实例对象都可以访问类变量类变量只能由类修改&#xff0c;实例对象…

MySQL 关联表批量修改(数据同步)

update table1 t1 ,table2 t2 set t1.field1 t2.field2 where t1.id t2.id 转载于:https://www.cnblogs.com/52php/p/5677908.html

sourcetree不好做到的一些git操作

2019独角兽企业重金招聘Python工程师标准>>> 日常中我们有很多操作通过sourcetree就可以实现界面化操作&#xff0c;但是有一些场景不好去实现&#xff0c;这里总结下&#xff1a; 场景1&#xff1a;我们有个A分支&#xff0c;需要跟master分支合并等待上线&#xf…

vue大括号里接受一个函数_vue源码探究(第四弹)

vue源码探究&#xff08;第四弹&#xff09;结束了上一part的数据代理&#xff0c;这一部分主要讲讲vue的模板解析&#xff0c;感觉这个有点难理解&#xff0c;而且内容有点多&#xff0c;hhh。模板解析废话不多说&#xff0c;先从简单的入手。按照之前的套路&#xff0c;先举一…

类级别的分装 ---四种访问级别

privateprivate成员为类的私有性质&#xff0c;仅有类本身和友元可以访问&#xff1b;protected和private类似&#xff0c;区别于protected可以被该类所有派生类访问&#xff1b;publicpublic的成员可以被外界的所有客户代码直接访问published和public的区别仅在于published的成…

python自省与反射

DAY 5. python自省 这是很久之前写的&#xff0c;当时对自省和反射的概念没理解&#xff0c;学习Java以后多了一点理解&#xff0c;自省是获取对象的能力&#xff0c;反射是操纵对象的能力&#xff0c;python中使用getattr()和setattr()实现反射&#xff0c;而其他的则是自省&…

vb.net 窗体接收键盘事件_(十五)C#WinFrom自定义控件系列-键盘(二)

前提入行已经7,8年了&#xff0c;一直想做一套漂亮点的自定义控件&#xff0c;于是就有了本系列文章。本系列文章将讲解各种控件的开发及思路&#xff0c;欢迎各位批评指正。此系列控件开发教程将全部在原生控件基础上进行重绘开发&#xff0c;目标的扁平化、漂亮、支持触屏。如…

centos下cmake安装

步骤一、安装gcc等必备程序包&#xff08;已安装则略过此步&#xff0c;用gcc -v检测&#xff09; yum install -y gcc gcc-c make automake 步骤二、安装wget &#xff08;已安装则略过此步&#xff09; yum install -y wget 步骤三、获取CMake源码包 wget http://www.cmake.…

python 生成式,迭代器,生成器

DAY 6. 生成式,迭代器&#xff0c;生成器 6.1 生成式 6.1.1 列表生成式 list [index for index in range(10)]6.1.2 字典生成式 dict {zhangsan: 10,lisi: 12,wangwu: 18 } # 实现键值互换 dict {k:v for v,k in dict.items() if k > 12}6.1.3 集合生成式 # 100以内…

shell MAC 地址 校验

/**************************************************************************************** shell MAC 地址 校验* 说明&#xff1a;* 要对MAC地址进行校验&#xff0c;记录一下正则表达式写法&#xff0c;有些方法在PC上验证是可行的&…

移动端Web开发如何处理横竖屏

<!Doctype html> <html> <head> <meta charset"utf-8"> <meta id"viewport" name"viewport" content"widthdevice-width,initial-scale1.0;"> <title>横竖屏切换检测</title> <style ty…

恩智浦智能车大赛2020_内蒙古科技大学第九届智能车大赛校内公开赛总决赛

为了激发学生的创新意识&#xff0c;提高学生的动手能力&#xff0c;培养团队合作意识&#xff0c;秉承“实践源于真知&#xff0c;创新放飞梦想”的思想。2020年12月6日&#xff0c;内蒙古科技大学第九届智能车大赛总决赛如约而至。本次大赛有来自各院系的223支队伍报名参加了…

python格式化字符串的三种方法(%,format,f-string)

DAY 7. 格式化字符串 到目前为止&#xff0c;我所知道的&#xff0c;python格式化字符串有三种方法&#xff0c;第一是早期就有的%&#xff0c;其次是2.5之后的format(),还有就是3.6添加的f字符串调试 7.1 %格式化字符串 %格式化字符串是python最早的&#xff0c;也是能兼容…

Android App 优化之 ANR 详解

为了便于阅读, 应邀将Android App性能优化系列, 转移到掘金原创上来.掘金的新出的"收藏集"功能可以用来做系列文集了. 今天先来聊聊ANR. 1, 你碰到ANR了吗 在App使用过程中, 你可能遇到过这样的情况: 恭喜你, 这就是传说中的ANR. 1.1 何为ANR ANR全名Application Not…

微信高级群发接口正文乱码解决方案

content里面的内空如果含有html标签的话&#xff0c;需要对内容进行一下转义。如果里面含有style".."类似于这样的带""号的内容的话&#xff0c;就更需要注意了。 foreach ($news as &$item) {foreach ($item as $key > $val){if ($key content){$…