策略模式(strategy pattern)

策略模式:

    定义了一个算法族,分别把每个算法封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

结构图:

C++实现:

class calculateStrategy {
public:
    virtual int calculate(int value1, int value2) = 0;
};

class Plus : public calculateStrategy {
public:
    int calculate(int value1, int value2) { return value1 + value2;}
};

class Minus : public calculateStrategy {
public:
    int calculate(int value1, int value2) { return value1 - value2;}
};

class Calculator {
private:
    calculateStrategy *cs;
public:
    Calculator(calculateStrategy *strategy): cs(strategy) {}
    int calculate(int value1, int value2)
    {
        return cs->calculate(value1, value2);
    }
    void setStrategy(calculateStrategy *strategy) { cs = strategy; };
    ~Calculator() { delete cs; }
};

int main()
{
    calculateStrategy *strategy = new Plus;
    Calculator cal(strategy);
    cout << cal.calculate(1, 2) << endl;
    delete strategy;

    strategy = new Minus;
    cal.setStrategy(strategy);
    cout << cal.calculate(1, 2) << endl;
    //delete strategy;
}

     策略模式使用了一个非常重要的设计原则:多用组合,少用继承。组合和继承的简单比较如下:

1. 在继承关系中,父类的内部细节对子类可见。父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类行为。
而在组合关系中,整体类和局部类之间不会去关心各自的实现细节,即它们之间的实现细节是不可见的。

2. 继承关系在编译时刻静态定义,子类无法在运行时刻改变从父类继承来的实现。组合关系在运行时刻动态定义,支持动态改变。

再贴张对比图:

组 合 关 系

继 承 关 系

优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立

缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性

优点:具有较好的可扩展性

缺点:支持扩展,但是往往以增加系统结构的复杂度为代价

优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象

缺点:不支持动态继承。在运行时,子类无法选择不同的父类

优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口

缺点:子类不能改变父类的接口

缺点:整体类不能自动获得和局部类同样的接口

优点:子类能自动继承父类的接口

缺点:创建整体类的对象时,需要创建所有局部类的对象

优点:创建子类的对象时,无须创建父类的对象

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

reference:

面向对象之继承和组合浅谈

posted @ 2015-08-17 11:27  Sawyer Ford  阅读(250)  评论(0编辑  收藏  举报