• 模式设计-strategy


    转自:http://www.cnblogs.com/jiese/p/3181099.html

    Strategy策略模式
    作用:定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

    UML图:



    Strategy模式将逻辑(算法)封装到一个类(Context)里面,通过组合的方式将具体算法的实现在组合对象中实现,再通过委托的方式将抽象接口的实现委托给组合对象实现

    将算法的逻辑抽象接口(DoAction)封装到一个类中(Context),再通过委托的方式将具体的算法实现委托给具体的Strategy类来实现(ConcreteStrategeA类)

    Stragegy类,定义所有支持的算法的公共接口
    ConcreteStrategy,封装了具体的算法或行为,继承于Strategy
    Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用

    策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类于使用算法类之间的耦合。

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

    策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

    策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

    在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。这本身并没有解除客户端需要选择判断的压力。

    代码如下:

    Strategy.h

    复制代码
     1 #ifndef _STRATEGY_H_
     2 #define _STRATEGY_H_
     3 
     4 class Strategy
     5 {
     6 public:
     7     ~Strategy();
     8     virtual void AlgrithmInterface()=0;
     9 protected:
    10     Strategy();
    11 private:
    12 };
    13 
    14 class ConcreteStrategyA : public Strategy
    15 {
    16 public:
    17     ConcreteStrategyA();
    18     ~ConcreteStrategyA();
    19     virtual void AlgrithmInterface();
    20 protected:
    21 private:
    22 };
    23 
    24 class ConcreteStrategyB : public Strategy
    25 {
    26 public:
    27     ConcreteStrategyB();
    28     ~ConcreteStrategyB();
    29     virtual void AlgrithmInterface();
    30 protected:
    31 private:
    32 };
    33 
    34 /*这个类是Strategy模式的关键,
    35   也是Strategy模式和Template模式的根本区别所在。
    36   *Strategy通过“组合”(委托)方式实现算法(实现)的异构,
    37   而Template模式则采取的是继承的方式
    38   这两个模式的区别也是继承和组合两种实现接口重用的方式的区别
    39 */
    40 class Context
    41 {
    42 public:
    43     Context(Strategy*);
    44     ~Context();
    45     void DoAction();
    46 private:
    47     Strategy* _strategy;
    48 };
    49 #endif
    复制代码

    Strategy.cpp

    复制代码
     1 #include "Strategy.h"
     2 #include "iostream"
     3 
     4 using namespace std;
     5 
     6 Strategy::Strategy()
     7 {}
     8 
     9 Strategy::~Strategy()
    10 {}
    11 
    12 ConcreteStrategyA::ConcreteStrategyA()
    13 {}
    14 
    15 ConcreteStrategyA::~ConcreteStrategyA()
    16 {}
    17 
    18 void ConcreteStrategyA::AlgrithmInterface()
    19 {
    20     cout << "ConcreteStrategyA::AlgrithmInterface" << endl;
    21 }
    22 
    23 ConcreteStrategyB::ConcreteStrategyB()
    24 {}
    25 
    26 ConcreteStrategyB::~ConcreteStrategyB()
    27 {}
    28 
    29 void ConcreteStrategyB::AlgrithmInterface()
    30 {
    31     cout << "ConcreteStrategyB::AlgrithmInterface" << endl;
    32 }
    33 
    34 Context::Context(Strategy* strategy)
    35 {
    36     this->_strategy = strategy;
    37 }
    38 
    39 Context::~Context()
    40 {
    41     delete this->_strategy;
    42 }
    43 
    44 void Context::DoAction()
    45 {
    46     this->_strategy->AlgrithmInterface();
    47 }
    复制代码

    main.cpp

    复制代码
     1 #include "Strategy.h"
     2 
     3 int main()
     4 {
     5     /*
     6     Strategy模式和Template模式实际是实现一个抽象接口的两种方式:继承和组合之间的区别。
     7     要实现一个抽象接口,继承是一种方式:我们将抽象接口声明在基类中,将具体的实现放在具体子类中。
     8     组合(委托)是另外一种方式:我们将接口的实现放在被组合对象中,将抽象接口放在组合类中。
     9     这两种方式各有优缺点
    10     */
    11     //策略A与B可替换
    12     Strategy* pStr = new ConcreteStrategyA();
    13     Context* pcon = new Context(pStr);
    14     pcon->DoAction();
    15 
    16     pStr = new ConcreteStrategyB();
    17     pcon = new Context(pStr);
    18     pcon->DoAction();
    19 
    20     return 0;
    21 }
    复制代码
  • 相关阅读:
    XML文件操作指南
    数字判断和文本框提交事件,WEB SERVICE等
    【转】JS回车提交
    nchar,char,varchar与nvarchar区别
    .NET对象的序列化
    这是发布的第一篇随笔
    Eclipse!!!!!!!!!!!!!!!!!!
    关于JLink驱动升级后不能使用的解决方法
    Python基本问题笔记
    用Python写的学校图书馆视频下载工具
  • 原文地址:https://www.cnblogs.com/jameszhan/p/strategy.html
Copyright © 2020-2023  润新知