策略模式(strategy)——组件协作类,行为型模式

在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂,而且有时候支持不使用的算法也是一个性能负担。

如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

这里提到一个策略模式,举个例子来说吧,这是对笔者项目的一种思考:

还是远控软件:

 我们来看step10和step12。由于采用的是完成端口模型,这里得先在主对话框中的函数走一趟,然后去相应的子对话框。目前的实现方法呢,是Completion Key中有一个字段叫DlgID,也就是在主对话框中设计了一个函数,里边有一个switch结构,用于判断Completion Key中的DlgID到底是什么,然后再去相应的对话框下处理数据。

这样做的问题是什么呢?你既然用了Switch,那就必然要把每一个功能的逻辑写一遍。第一,代码非常冗余;第二,在该函数中支持了不必要的算法代码。

既然这一块的代码要经常改变(针对不同的具体功能)。那我干脆在Completion Key中设置一个函数指针字段,用来放不同套接字所对应的Handle函数,直接把数据丢到处理函数中去。实现Handle函数和主对话框处理函数的解绑。代码也会更加简洁。

当然上述只是笔者个人的自省。如果这样发出来没有科普价值,给大家分享一下李建忠老师的例子:

enum TaxBase {
	CN_Tax,
	US_Tax,
	DE_Tax,
	FR_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***********
        }
		else if (tax == FR_Tax){  //更改
			//...
		}

        //....
     }
    
};

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){
		//.........
	}
};


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); //多态调用
        //...
    }
    
};




给大家解释一下。

整体来说呢,是一个计算税的需求。要对不同国家的税进行计算,但计算方法不一样。

第一个例子是没有使用策略模式,把所有的税计算过程都写进来了,当需要更新的时候,再加一个if分支就好了,一点都不优雅。

第二个例子是用了策略模式的。设计一个抽象类Tax,CNTax、ENTax等都继承自Tax,并重写Calculate函数,这样使用的时候我new一个具体对象(Tax,里氏替换原则)出来,直接调用Calculate函数就好,我不用操心它到底是哪个国家的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值