一、基本原理
策略模式和 Template 模式要解决的问题是相同(类似)的,都是为了给业务逻辑(算法)具体实现和抽象接口之间的解耦。策略模式将逻辑(算法)封装到一个类(Context)里面,通过组合的方式将具体算法的实现在组合对象中实现,再通过委托的方式将抽象接口的实现委托给组合对象实现。
二、基本模式
关键就是将逻辑抽象接口(DoAction)封装到一个类中(Context),再通过委托的方式将具体的算法实现委托给具体的策略类来实现(ConcreteStrategeA类)。
三、具体代码实现
//基类定义抽象接口
class Strategy{
public:
Strategy();
virtual ~Strategy();
virtual void AlgrithmInterface() = 0;
};
Strategy::Strategy(){
}
Strategy::~Strategy(){
cout<<"~Strategy....."<<endl;
}
void Strategy::AlgrithmInterface(){
}
//具体类,实现具体算法
class ConcreteStrategyA:public Strategy{
public:
ConcreteStrategyA();
virtual ~ConcreteStrategyA();
void AlgrithmInterface();
};
ConcreteStrategyA::ConcreteStrategyA(){
}
ConcreteStrategyA::~ConcreteStrategyA(){
cout<<"~ConcreteStrategyA....."<<endl;
}
void ConcreteStrategyA::AlgrithmInterface(){
cout<<"test ConcreteStrategyA....."<<endl;
}
//具体类,实现具体的算法
class ConcreteStrategyB:public Strategy{
public:
ConcreteStrategyB();
virtual ~ConcreteStrategyB();
void AlgrithmInterface();
};
ConcreteStrategyB::ConcreteStrategyB(){
}
ConcreteStrategyB::~ConcreteStrategyB(){
cout<<"~ConcreteStrategyB....."<<endl;
}
void ConcreteStrategyB::AlgrithmInterface(){
cout<<"test ConcreteStrategyB....."<<endl;
}
/**
*这个类是 Strategy 模式的关键,也是 Strategy模式和Template模式的根本区别所在。
**Strategy 通过“组合”(委托)方式实现算法(实现)的异构,而Template 模式则采取的是继承的方式,
**这两个模式的区别也是继承和组合两种实现接口重用的方式的区别
*/
class Context{
public:
Context(Strategy* stg);
~Context();
void DoAction();
private:
Strategy* _stg;
};
Context::Context(Strategy* stg){
_stg = stg;
}
Context::~Context(){
if (!_stg)
delete _stg;
}
**void Context::DoAction(){
_stg->AlgrithmInterface();
}**
int main(int argc,char* argv[]){
Strategy* ps = new ConcreteStrategyA();
Context* pc = new Context(ps);
pc->DoAction();
if (NULL != pc)
delete pc;
return 0;
}
四、比较
(1)策略模式和 Template 模式实际是实现一个抽象接口的两种方式:继承和组合之间的区别。要实现一个抽象接口,继承是一种方式:我们将抽象接口声明在基类中,将具体的实现放在具体子类中(模板模式)。组合(委托)是另外一种方式:我们将接口的实现放在被组合对象中,将抽象接口放在组合类中(策略模式)
(2)继承
优点:易于修改和扩展那些被复用的实现
缺点:①破坏了封装性,继承中父类的实现细节暴露给子类了;②当父类的实现更改时,其所有子类将不得不随之改变;③从父类继承而来的实现在运行期间不能改变(编译期间就已经确定了)
(3)组合
优点:①封装性好;②实现和抽象的依赖性很小(采用委托的方式实现具体算法)(组合对象和被组合对象之间的依赖性小);③可以在运行期间动态定义实现(通过一个指向相同类型的指针,典型的是抽象基类的指针)。
缺点:系统中对象过多。
原则:优先使用(对象)组合,而非(类)继承
注:原文网页:http://www.weixueyuan.net/view/1258.html
仅做学习,无任何商业用途