源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

C++设计模式之策略模式

  • 时间:2021-12-27 06:37 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:C++设计模式之策略模式
[b]前言[/b] 刚刚加班回来;哎,公司规定平时加班只有10块钱的餐补;星期六和星期天加班,只给串休假;在国家规定的节假日按照3倍工资发放。那么对于这么多的计算加班费的方法,公司的OA系统是如何进行做的呢?这就要说到今天我这里总结的策略设计模式了。 [b]策略模式[/b] 在GOF的《设计模式:可复用面向对象软件的基础》一书中对策略模式是这样说的:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。该模式使得算法可独立于使用它的客户而变化。 策略模式为了适应不同的需求,只把变化点封装了,这个变化点就是实现不同需求的算法,但是,用户需要知道各种算法的具体情况。就像上面的加班工资,不同的加班情况,有不同的算法。我们不能在程序中将计算工资的算法进行硬编码,而是能自由的变化的。这就是策略模式。 [b]UML类图[/b] [img]http://files.jb51.net/file_images/article/201410/201410993901100.png?2014999399[/img] Strategy:定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法; ConcreteStrategy:实现Strategy接口的具体算法; Context:使用一个ConcreteStrategy对象来配置;维护一个对Stategy对象的引用,同时,可以定义一个接口来让Stategy访问它的数据。 [b]使用场合[/b] 当存在以下情况时使用Strategy模式: 1.许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法; 2.需要使用一个算法的不同变体; 3.算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构; 4.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以替代这些条件语句。(是不是和[url=http://www.1sucai.cn/article/55997.htm]状态模式[/url]有点一样哦?) [b]代码实现[/b] 首先实现最单纯的策略模式,代码如下:
[u]复制代码[/u] 代码如下:
#include <iostream> using namespace std;   // The abstract strategy class Strategy { public:      virtual void AlgorithmInterface() = 0; };   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,而这样就莫名的增加了客户端的压力,让客户端的复杂度陡然增加了。那么,我们就可以借鉴简单工厂模式,使策略模式和简单工厂模式相结合,从而减轻客户端的压力,代码实现如下:
[u]复制代码[/u] 代码如下:
#include <iostream> using namespace std;   // Define the strategy type typedef enum StrategyType {     StrategyA,     StrategyB,     StrategyC }STRATEGYTYPE;   // The abstract strategy class Strategy { public:     virtual void AlgorithmInterface() = 0;     virtual ~Strategy() = 0; // 谢谢hellowei提出的bug,具体可以参见评论 };   Strategy::~Strategy() {}   class ConcreteStrategyA : public Strategy { public:     void AlgorithmInterface()     {         cout << "I am from ConcreteStrategyA." << endl;     }       ~ConcreteStrategyA(){} };   class ConcreteStrategyB : public Strategy { public:     void AlgorithmInterface()     {         cout << "I am from ConcreteStrategyB." << endl;     }       ~ConcreteStrategyB(){} };   class ConcreteStrategyC : public Strategy { public:     void AlgorithmInterface()     {         cout << "I am from ConcreteStrategyC." << endl;     }       ~ConcreteStrategyC(){} };   class Context { 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();     }   private:     Strategy *pStrategy; };   int main() {     Context *pContext = new Context(StrategyA);     pContext->ContextInterface();       if (pContext) delete pContext; }
在上面这个代码中,其实,我们可能看到的更多的是简单工厂模式的应用,我们将策略模式将简单工厂模式结合在了一起,让客户端使用起来更轻松。 [b]总结[/b] 策略模式和状态模式,是大同小异的;状态模式讲究的是状态的变化,和不同状态下,执行的不同行为;而策略模式侧重于同一个动作,实现该行为的算法的不同,不同的策略封装了不同的算法。策略模式适用于实现某一功能,而实现该功能的算法是经常改变的情况。在实际工作中,遇到了实际的场景,可能会有更深的体会。比如,我们做某一个系统,该系统可以适用于各种数据库,我们都知道,连接某一种数据库的方式是不一样的,也可以说,连接数据库的“算法”都是不一样的。这样,我们就可以使用策略模式来实现不同的连接数据库的策略,从而实现数据库的动态变换。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部