C++设计模式——策略模式
策略模式
在GOF的《设计模式:可复用面向对象软件的基础》一书中对策略模式是这样说的:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。该模式使得算法可独立于使用它的客户而变化。
策略模式为了适应不同的需求,只把变化点封装了,这个变化点就是实现不同需求的算法,但是,用户需要知道各种算法的具体情况。就像上面的加班工资,不同的加班情况,有不同的算法。我们不能在程序中将计算工资的算法进行硬编码,而是能自由的变化的。这就是策略模式。
UML类图
Strategy:定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法;
ConcreteStrategy:实现Strategy接口的具体算法;
Context:使用一个ConcreteStrategy对象来配置;维护一个对Stategy对象的引用,同时,可以定义一个接口来让Stategy访问它的数据。
使用场合
当存在以下情况时使用Strategy模式:
- 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法;
- 需要使用一个算法的不同变体;
- 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构;
- 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以替代这些条件语句。(是不是和状态模式有点一样哦?)
代码实现
首先实现最单纯的策略模式,代码如下:
#include <iostream>
using namespace std; // The abstract strategy
class Strategy
{
public:
virtual void AlgorithmInterface() = ;
}; class ConcreteStrategyA : public Strategy
{
public:
void AlgorithmInterface()
{
cout<<"I am from ConcreteStrategyA."<<endl;
}
}; class ConcreteStrategyB : public Strategy
{
public:
void AlgorithmInterface()
{
cout<<"I am from ConcreteStrategyB."<<endl;
}
}; class ConcreteStrategyC : public Strategy
{
public:
void AlgorithmInterface()
{
cout<<"I am from ConcreteStrategyC."<<endl;
}
}; class Context
{
public:
Context(Strategy *pStrategyArg) : pStrategy(pStrategyArg)
{
}
void ContextInterface()
{
pStrategy->AlgorithmInterface();
}
private:
Strategy *pStrategy;
}; int main()
{
// Create the Strategy
Strategy *pStrategyA = new ConcreteStrategyA;
Strategy *pStrategyB = new ConcreteStrategyB;
Strategy *pStrategyC = new ConcreteStrategyC;
Context *pContextA = new Context(pStrategyA);
Context *pContextB = new Context(pStrategyB);
Context *pContextC = new Context(pStrategyC);
pContextA->ContextInterface();
pContextB->ContextInterface();
pContextC->ContextInterface(); if (pStrategyA) delete pStrategyA;
if (pStrategyB) delete pStrategyB;
if (pStrategyC) delete pStrategyC; if (pContextA) delete pContextA;
if (pContextB) delete pContextB;
if (pContextC) delete pContextC;
}
在实际操作的过程中,我们会发现,在main函数中,也就是在客户端使用策略模式时,会创建非常多的Strategy,而这样就莫名的增加了客户端的压力,让客户端的复杂度陡然增加了。那么,我们就可以借鉴简单工厂模式,使策略模式和简单工厂模式相结合,从而减轻客户端的压力,代码实现如下:
/*!
* \file StrategePatternDemo.cpp
* \date 2016/08/14 19:56
*
* \author ranjiewen
* \contact: ranjiewen@outlook.com
*
* \brief
*
* TODO: long description
*
* \note
*/ #include <iostream>
using namespace std; typedef enum StrategyType
{
StrategyA,
StrategyB,
StrategyC
}; class Strategy
{
public:
virtual void AlgorithmInterface() = ;
virtual ~Strategy() = ; //基类申请为虚析构函数 };
Strategy::~Strategy(){} class ConcreteStrategyA :public Strategy
{
public:
void AlgorithmInterface()
{
cout << "I'm from ConcreteStrategyA." << endl;
}
~ConcreteStrategyA(){} }; class ConcreteStrategyB :public Strategy
{
public:
void AlgorithmInterface()
{
cout << "I'm from ConcreteStrategyB." << endl;
}
~ConcreteStrategyB(){}
}; class ConcreteStrategyC :public Strategy
{
public:
void AlgorithmInterface()
{
cout << "I'm from ConcreteStrategyC." << endl;
}
~ConcreteStrategyC(){}
}; class Context
{
private:
Strategy* pStrategy;
public:
Context(StrategyType strategyType)
{
switch (strategyType)
{
case StrategyA:
pStrategy = new ConcreteStrategyA;
break;
case StrategyB:
pStrategy = new ConcreteStrategyB;
break;
case StrategyC:
pStrategy = new ConcreteStrategyC;
break;
default:
break;
}
}
~Context()
{
if (pStrategy)
{
delete pStrategy;
}
} void ContextInterface()
{
if (pStrategy)
{
pStrategy->AlgorithmInterface();
}
}
}; int main()
{
Context* pContext = new Context(StrategyA);
pContext->ContextInterface();
return ;
}
在上面这个代码中,其实,我们可能看到的更多的是简单工厂模式的应用,我们将策略模式将简单工厂模式结合在了一起,让客户端使用起来更轻松。
总结
策略模式和状态模式,是大同小异的;状态模式讲究的是状态的变化,和不同状态下,执行的不同行为;而策略模式侧重于同一个动作,实现该行为的算法的不同,不同的策略封装了不同的算法。策略模式适用于实现某一功能,而实现该功能的算法是经常改变的情况。在实际工作中,遇到了实际的场景,可能会有更深的体会。比如,我们做某一个系统,该系统可以适用于各种数据库,我们都知道,连接某一种数据库的方式是不一样的,也可以说,连接数据库的“算法”都是不一样的。这样,我们就可以使用策略模式来实现不同的连接数据库的策略,从而实现数据库的动态变换。
C++设计模式——策略模式的更多相关文章
- 15. 星际争霸之php设计模式--策略模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)
[.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...
- linkin大话设计模式--策略模式
linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi] 策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...
- [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)
[.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...
- 设计模式-策略模式(Strategy Model)
1.概述 在开发过程中常常会遇到类似问题,实现一个功能的时候往往有多种算法/方法(策略),我们可以根据环境的不同来使用不同的算法或策略来实现这一功能. 如在人物比较排序的实现中,我们有 ...
- java设计模式 策略模式Strategy
本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...
- [Head First设计模式]策略模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- javascript 设计模式-----策略模式
在<javascript设计模式>中,作者并没有向我们介绍策略模式,然而它却是一种在开发中十分常见的设计模式.最常见的就是当我们遇到一个复杂的表单验证的时候,常常需要编写一大段的if和el ...
- JAVA 设计模式 策略模式
用途 Title 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 策略模式是一种行为型模式. 结构
- PHP设计模式-策略模式 转
策略模式(Strategy Pattern) 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因为这个 ...
随机推荐
- 通过注册表查找oracle_home的位置
运行regedit进入注册表 ctrl+f查找oracle_home
- jquery中json数据转换为字典
首先在前台页面中的json数据为 var recipe = {}; recipe["name"] = $("#name").val(); recipe[&quo ...
- Tiny6410 交叉编译helloworld程序
在工作目录下建立helloworld.c文件 #include <stdio.h> main() { printf("helloworld!\n"); } 保存关闭后. ...
- Spring/Hibernate 应用性能优化的7种方法
对于大多数典型的 Spring/Hibernate 企业应用而言,其性能表现几乎完全依赖于持久层的性能.此篇文章中将介绍如何确认应用是否受数据库约束,同时介绍七种常用的提高应用性能的速成法.本文系 O ...
- C语言的左位移能不能超过8位?
C语言的左位移能不能超过8位?比如b=a<<20; 这样可以不?如果可以,一个字节只有8个位,左移20位是不是连右边其它字节的12个位(20-8)也一起左移? 字符变量左移八次后,所有的位 ...
- 跨平台Unicode与UTF8互转代码
参考来源:http://blog.csdn.net/flying8127/article/details/1598521 在原来原基础上,将代码整理,并加强安全性. 并按照WindowsAPI设计, ...
- 跟随屏幕滚动层、遮罩层、获取Div相对定位、整个屏幕、html文档的jquery基本操作
一.层跟随屏幕滚动 <div style="width:120px;height:120px;border:1px solid red; position:absolute; left ...
- 【转】VMware设置共享文件夹之后Ubuntu中看不到怎么办?
一.共享文件夹设置好了,但是在虚拟机中的Ubuntu系统下却看不到,怎么办? 一种可能的原因是系统没有自动挂载,解决办法: 1.安装: sudo apt-get insta ...
- DX 绘制位图
简单地学习了四个API: HRESULT CreateOffscreenPlainSurface( [in] UINT Width, // 宽度 [in] UINT Height, // 高度 [in ...
- matlab 设置横纵坐标刻度的字体!!
set(gca,'FontSize',16) %%设置横纵坐标字体的大小