- 前言
- 一、策略模式( Strategy 模式)
- 二、具体源码
- 1.Strategy.h
- 2.Strategy.cpp
- 3.Context.h
- 4.Context.cpp
- 5.main.cpp
- 三、运行结果
- 总结
前言
Strategy 模式和 Template 模式要解决的问题是相同的,都是为了给业务逻辑具体实现和抽象接口之间的解耦。Strategy 模式将逻辑封装到一个类里面,通过组合的方式将具体算法的实现在组合对象中实现,再通过委托的方式将抽象接口的实现委托给组合对象实现。
一、策略模式( Strategy 模式)
Strategy 模式的关键就是将算法的逻辑抽象接口(DoAction)封装到一个类中(Context),再通过委托的方式将具体的算法实现委托给具体的 Strategy 类来实现(ConcreteStrategeA类或者oncreteStrategeB类)。UML图如下:
代码如下(示例):
#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 模式和 Template 模式解决了类似的问题,两者实际是实现一个抽象接口的两种方式:继承和组合之间的区别。要实现一个抽象接口,继承是一种方式:我们将抽象接口声明在基类中,将具体
的实现放在具体子类中。组合(委托)是另外一种方式:我们将接口的实现放在被组合对象中,将抽象接口放在组合类中。
这两种方式各有优缺点,如下:
- 继承:易于修改和扩展那些被复用的实现。但是这样破坏了封装性,继承中父类的实现细节暴露给子类了;当父类的实现更改时,其所有子类将不得不随之改变;而且,从父类继承而来的实现在运行期间不能改变(编译期间就已经确定了)。
- 组合:“黑盒”复用,因为被包含对象的内部细节对外是不可见的,封装性好;另外,实现和抽象的依赖性很小(组合对象和被组合对象之间的依赖性小),可以在运行期间动态定义实现(通过一个指向相同类型的指针,典型的是抽象基类的指针)。但是,这样设计的缺点也是显而易见的,会引起系统中对象过多。
从上面对比中我们可以看出,组合相比继承可以取得更好的效果,因此在面向对象的设计中的有一条很重要的原则就是:优先使用(对象)组合,而非(类)继承(FavorComposition Over Inheritance)。
本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
本文名称:设计模式【14】——策略模式(Strategy模式)-创新互联
路径分享:http://lswzjz.com/article/ccdjpd.html