策略模式

来源:互联网 发布:linux 用代码链接网络 编辑:程序博客网 时间:2024/05/16 19:08

一、基本原理
策略模式和 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
仅做学习,无任何商业用途

0 0