23种设计模式---策略模式

策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。通过将算法封装在独立的策略类中,可以避免在客户端代码中使用复杂的条件判断,提高代码的可维护性和可扩展性。例如,在财务报表计算中,使用策略模式可以轻松添加或修改税率算法,而不需要改动原有代码。这种模式的优点包括算法的自由切换、良好的扩展性,但也会导致策略类的增加并需要暴露策略接口。
摘要由CSDN通过智能技术生成

策略模式

动机

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

解决方法

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

例子

计算财务报表(支持跨国税率):
一种实现:

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. enum添加税率算法

    enum TaxBase
    {
    	CN_Tax,
    	US_Tax,
    	DE_Tax,
    	FR_Tax       // 更改
    };
    
  2. 修改对应税率计算

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

当添加了一个税率需要改变地方(其实就是一个扩展,原来的代码无需改变):

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

优缺点

优点:算法可以自由切换。避免使用多重条件判断。扩展性良好。继承可以析取算法的公共部分。可以为每个算法单独定义测试类。

缺点:策略类会增多。所有策略类都需要对外暴露。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值