设计模式二 策略模式(Strategy Method)

目录

1.模式简介

1.1 策略模式的动机(Motivation)

1.2 模式定义

1.3 图解

2.原来的时候面对变化

3.策略模式下面对变化

4.一些注意点

4.1 策略模式的缺点与优点

4.2 真正的复用

4.3 如何面对大量的if...else或者switch...case

5.总结


0.阅读

模块的可插拔设计(策略模式)

策略模式实现可拓展可插拔的功能

1.模式简介

1.1 策略模式的动机(Motivation)

在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担.如何在运行是根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

1.2 模式定义

定义一些列算法,把它们一个个封装起来,并且使得它们可以互相替换(变化),该模式使得算法可以独立于使用它的客户程序(稳定)而变化(拓展,子类化).

---《设计模式》GoF

1.3 图解

  

 2.原来的时候面对变化

// 违反开闭原则
// 开闭原则: 对扩展开放,对修改关闭
#include <iostream>
using namespace std;
enum TaxBase{
     CN_Tax,
     US_Tax,
     DE_Tax,
     FR_Tax // 更改
};


class SalesOrder{
public:
     TaxBase tax;
public:
     void CalculateTax(){
          if(tax == CN_Tax){
              cout << "这个是中国的税法计算方法"<< endl;
          }
          else if(tax == US_Tax){
              cout << "这个是美国的税法计算方法"<< endl;
          }
          else if(tax == DE_Tax){
              cout << "这个是德国的税法计算方法"<< endl;
          }ss
          else if(tax == FR_Tax){ // 更改
              cout << "这个是法国的税法计算方法"<< endl;
          }
     }
};
int main(){
     SalesOrder obj_tax_cal;
     obj_tax_cal.tax = CN_Tax;
     obj_tax_cal.CalculateTax();

}

3.策略模式下面对变化


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{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};

class DETax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};



//扩展
//*********************************
class FRTax : public TaxStrategy{
public:
	virtual double Calculate(const Context& context){
		//.........
	}
};

// SalesOrder这个类是不再变化的,不需要再编码的,得到了复用性.
class SalesOrder{
private:
    TaxStrategy* strategy;

public:
    SalesOrder(StrategyFactory* strategyFactory){
        this->strategy = strategyFactory->NewStrategy();
    }
    ~SalesOrder(){
        delete this->strategy;
    }

    public double CalculateTax(){
           //...
        Context context();
        
        double val = 
            strategy->Calculate(context); //多态调用
          //...
    }
    
};

4.一些注意点

4.1 策略模式的缺点与优点


类变多了.策略模式一样要有判断,判断转移到工厂中去了,后面的人看不见工厂就不会对
工厂有错误修改.

4.2 真正的复用

真正的复用是编译之后,测试之后,部署之后,再需要改需求的时候,代码是不需要改变的,
是二进制意义上的单位复用,而不是源代码的片段级别的复用.在一段代码底下补充一些代码往往会引入一些bug,
所以在源代码级别的复制粘贴我们是不推荐的,我们压根不将其称为复用性.

4.3 如何面对大量的if...else或者switch...case

当你的代码中出现了大量的if...else或者switch...case的时候,你是否嗅到了bad smell也许你
就该要好好的考虑是不是可以用策略模式了.当然如果if...else或者switch...case出现的情况是
固定不变的,那么这种情况下,也不一定就要用策略模式来进行编码设计.

5.总结

1.Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根
据需要在各个算法之间进行切换。
2.Strategy模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合.
含有许多条件判断语句的代码通常都需要Strategy模式.
3.如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省
对象开销。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值