设计模式【14】——策略模式(Strategy模式)-创新互联

文章目录
  • 前言
  • 一、策略模式( Strategy 模式)
  • 二、具体源码
    • 1.Strategy.h
    • 2.Strategy.cpp
    • 3.Context.h
    • 4.Context.cpp
    • 5.main.cpp
  • 三、运行结果
  • 总结

成都创新互联公司专注于企业营销型网站、网站重做改版、东兴网站定制设计、自适应品牌网站建设、HTML5商城网站制作、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为东兴等各大城市提供网站开发制作服务。
前言

Strategy 模式和 Template 模式要解决的问题是相同的,都是为了给业务逻辑具体实现和抽象接口之间的解耦。Strategy 模式将逻辑封装到一个类里面,通过组合的方式将具体算法的实现在组合对象中实现,再通过委托的方式将抽象接口的实现委托给组合对象实现。


一、策略模式( Strategy 模式)

Strategy 模式的关键就是将算法的逻辑抽象接口(DoAction)封装到一个类中(Context),再通过委托的方式将具体的算法实现委托给具体的 Strategy 类来实现(ConcreteStrategeA类或者oncreteStrategeB类)。UML图如下:
Strategy 模式示意图

二、具体源码 1.Strategy.h

代码如下(示例):

#ifndef _STRATEGY_H_ 
#define _STRATEGY_H_ 

#includeclass Strategy
{public:

  Strategy();
  virtual ~Strategy();
  virtual void AlgrithmInterface() = 0;

protected:

private:
};

class ConcreteStrategyA :public Strategy
{public:

  ConcreteStrategyA();
  virtual ~ConcreteStrategyA();
  void AlgrithmInterface();

protected:

private:
};

class ConcreteStrategyB :public Strategy
{public:

  ConcreteStrategyB();
  virtual ~ConcreteStrategyB();
  void AlgrithmInterface();

protected:
private:
};

#endif //_STRATEGY_H_
2.Strategy.cpp

代码如下(示例):

#include "Strategy.h"

Strategy::Strategy()
{}

Strategy::~Strategy()
{std::cout<< "~Strategy....."<< std::endl;
}

void Strategy::AlgrithmInterface()
{}

ConcreteStrategyA::ConcreteStrategyA()
{}

ConcreteStrategyA::~ConcreteStrategyA()
{std::cout<< "~ConcreteStrategyA....."<< std::endl;
}

void ConcreteStrategyA::AlgrithmInterface()
{std::cout<< "test ConcreteStrategyA....."<< std::endl;
}

ConcreteStrategyB::ConcreteStrategyB()
{}

ConcreteStrategyB::~ConcreteStrategyB()
{std::cout<< "~ConcreteStrategyB....."<< std::endl;
}

void ConcreteStrategyB::AlgrithmInterface()
{std::cout<< "test ConcreteStrategyB....."<< std::endl;
}
3.Context.h

代码如下(示例):

#pragma once
#ifndef _CONTEXT_H_ 
#define _CONTEXT_H_

#include "Strategy.h"

class Context
{public:

  Context(Strategy* stg);
  ~Context();
  void DoAction();

protected:
private:
  //Strategy 通过“组合”(委托)方式实现算法(实现)的异构,而 Template 模式则采取的是继承的方式 *这两个模式的区别也是继承和组合两种实现接口重用的方式的区别
  Strategy* _stg;
};

#endif //_CONTEXT_H_
4.Context.cpp

代码如下(示例):

#include "Context.h"

Context::Context(Strategy* stg)
{_stg = stg;
}

Context::~Context()
{if (!_stg)
    delete _stg;
}

void Context::DoAction()
{_stg->AlgrithmInterface();
}
5.main.cpp

代码如下(示例):

#include "Context.h"

int main(int argc, char* argv[])
{Strategy* ps = new ConcreteStrategyA();
  Context* pc = new Context(ps);

  Strategy* ps1 = new ConcreteStrategyB();
  Context* pc1 = new Context(ps1);

  pc->DoAction();
  pc1->DoAction();

  //释放申请的内存
  if (nullptr != pc)
    delete pc;
  if (nullptr != pc1)
    delete pc1;

  return 0;
}

三、运行结果

Strategy 模式运行结果如下:
 Strategy 模式运行结果


总结

从上述内容可以看出, Strategy 模式和 Template 模式解决了类似的问题,两者实际是实现一个抽象接口的两种方式:继承和组合之间的区别。要实现一个抽象接口,继承是一种方式:我们将抽象接口声明在基类中,将具体
的实现放在具体子类中。组合(委托)是另外一种方式:我们将接口的实现放在被组合对象中,将抽象接口放在组合类中。
这两种方式各有优缺点,如下:

  • 继承:易于修改和扩展那些被复用的实现。但是这样破坏了封装性,继承中父类的实现细节暴露给子类了;当父类的实现更改时,其所有子类将不得不随之改变;而且,从父类继承而来的实现在运行期间不能改变(编译期间就已经确定了)。
  • 组合:“黑盒”复用,因为被包含对象的内部细节对外是不可见的,封装性好;另外,实现和抽象的依赖性很小(组合对象和被组合对象之间的依赖性小),可以在运行期间动态定义实现(通过一个指向相同类型的指针,典型的是抽象基类的指针)。但是,这样设计的缺点也是显而易见的,会引起系统中对象过多。

从上面对比中我们可以看出,组合相比继承可以取得更好的效果,因此在面向对象的设计中的有一条很重要的原则就是:优先使用(对象)组合,而非(类)继承(FavorComposition Over Inheritance)。


本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


文章标题:设计模式【14】——策略模式(Strategy模式)-创新互联
转载来源:http://ybzwz.com/article/ccdjpd.html