设计模式---策略模式

来源:互联网 发布:微商城与淘宝的区别 编辑:程序博客网 时间:2024/06/12 23:19

1.组件协作模式

现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。

  1. Template Method
  2. Strategy
  3. Observer/Event

定义一系列算法,把他们一个个封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。   
                                                         -《设计模式》Gof

2.举例代码分析

下面是电子商务系统中订单里税的计算的伪代码,当支持跨国结算的计算场景,有中国,美国,德国三个国家;

enum TaxBase{    CN_Tax;    US_Tax;    DE_Tax;};class SalesOrder{    TaxBase tax;    public:    double CalculateTax(){        //...        if(tax == CN_Tax){            //CN...        }        else if(tax == US_Tax){            //US...        }        else if(tax == DE_Tax){            //DE...        }        //...    }};
  1. 在实际软件开发中,需求不断的变化。倘若需要增加一个国家呢,譬如法国,枚举类增加了一个FR_Tax,而且还要编写一段else-if法国的税算法。于是问题来了…
  2. 代价–重新编译,重新测试,重新部署…
  3. 以上代码的设计违背了开放封闭原则,即对扩展开放,对更改封闭。
  4. 以下是改进的代码
class TaxStrategy{    public:        virtual double Calculate(const context& context)=0;        virtual ~TaxStrategy(){}};class CNTax:public TaxStrategy{    public:        virtual double Calculate(const Context& context){            //***        }};class USTax:public TaxStrategy{...};class DETax:public TaxStrategy{...};class SalesOrder{    private:        TaxStrategy* strategy;    public:        SalesOrder(StrategyFactory* strategyFactory){            this->strategy = stategyFactory->NewStrategy;        }        ~SalesOrder(){              delete this->strategy;        }        public double CalculateTax(){            Context context()l            double val = Strategy->Calculate(context);//多态调用        }}
  1. 基类必须写一个虚的析构函数,不然多态的delete会出问题
  2. 规范时,应该把一个类放在一个文件里,采用多文件的方式,工程上的推荐做法
  3. 在SalesOrder类里实现多态变量,一般用指针,引用也可以用,但是会有一些问题,具体的老师也没有深挖
  4. 将前面的if-else里面一个国家的汇率转换成TaxStrategy一个一个的子类
  5. 采用了工厂模式—StrategyFactory,new出来不确定的Tax,返回类型由工厂模式确定。
  6. 增设法国,只需要编写一个法国的子类,调用代码不改变

“复用”面向对象与设计模式所讲的复用性所指的是编译单位,二进制层面的复用性。

3.结构图

这里写图片描述

4.要点总结

  1. Strategy及其子类为组件提供一系列可重用的算法,在运行时方便的根据需要在各个算法之间进行切换。
  2. 运行时进行多态的调用
  3. 提供了条件判断语句以外的另一种选择,解耦合的手法,出现条件判断语句时需要strategy的一种特征,《重构》里面提及的if-else和switch-case。
  4. if-else结构化分而治之的手法,但是可以用面向对象的抽象来解决问题。
  5. 时间轴的想法,即未来可能出现的第四种情况,第五种情况…这个就是典型的strategy模式。
  6. if-else里面的情况是绝对不变的时候,用这种模式。但是当业务频繁变化时,这个时候应该特别小心,“坏味道”使用策略模式应该小心。
  7. 代码具有良好的本地性

有时候支持不使用的算法也是一个性能负担—if-else很多的情况下,譬如只使用中国区的代码,但是其余的代码都装载内存里。
最好的执行模式(快):CPU的高级缓存>主存>硬盘

0 0