Strategy模式和Template模式要解决的问题是相同的,都是为了给业务逻辑具体实现和抽象接口之间的解耦。
Strategy模式将逻辑封装到一个类里面,通过组合的方式将具体算法的实现在组合对象中实现,再通过委托的方式将抽象接口的实现委托给组合对象实现。
Strategy.h
//strategy.h #ifndef _STRATEGY_H_ #define _STRATEGY_H_ class 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_Strategy.cpp
//Strategy.cpp #include "Strategy.h" #include <iostream> using namespace std; Strategy::Strategy() { } Strategy::~Strategy() { cout<<"~Strategy....."<<endl; } void Strategy::AlgrithmInterface() { } ConcreteStrategyA::ConcreteStrategyA() { } ConcreteStrategyA::~ConcreteStrategyA() { cout<<"~ConcreteStrategyA....."<<endl; } void ConcreteStrategyA::AlgrithmInterface() { cout<<"test ConcreteStrategyA....."<<endl; } ConcreteStrategyB::ConcreteStrategyB() { } ConcreteStrategyB::~ConcreteStrategyB() { cout<<"~ConcreteStrategyB....."<<endl; } void ConcreteStrategyB::AlgrithmInterface() { cout<<"test ConcreteStrategyB....."<<endl; }Context.h
//Context.h #ifndef _CONTEXT_H_ #define _CONTEXT_H_ class Strategy; /** *这个类是Strategy模式的关键,也是Strategy模式和Template模式的根本区别所在。 *Strategy通过“组合”(委托)方式实现算法(实现)的异构,而Template模式则采取的是继承的方式 *这两个模式的区别也是继承和组合两种实现接口重用的方式的区别 */ class Context { public: Context(Strategy* stg); ~Context(); void DoAction(); protected: private: Strategy* _stg; }; #endif //~_CONTEXT_H_Context.cpp
//Context.cpp #include "Context.h" #include "Strategy.h" #include <iostream> using namespace std; Context::Context(Strategy* stg) { _stg = stg; } Context::~Context() { if (!_stg) delete _stg; } void Context::DoAction() { _stg->AlgrithmInterface(); }
#include "Strategy.h" #include "Context.h" #include <iostream> using namespace std; int main(){ Strategy* ps = new ConcreteStrategyA(); Context* pc = new Context(ps); pc->DoAction(); if (NULL != pc) delete pc; return 0; }
继承和组合各有优缺点:
1、继承:
优点:1)易于修改和扩展被复用的实现;
缺点:1)破坏了封装性,继承中父类的实现细节暴露给了子类;
2)“白盒”复用
3)当父类的实现更改时,其所有子类将不得不随之改变
4)从父类继承而来的实现在运行期间不能改变
2、组合:
优点:1)“黑盒”复用,因为被包含对象的内部细节对外是不可见的
2)封装性好
3)实现和抽象的依赖性很小
4)可以在运行期间动态定义实现
缺点:
1)系统对象过多
原文:http://blog.csdn.net/starcuan/article/details/20370673