设计模式第四讲--Strategy 策略模式
1. “组件协作”模式:
现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚绑定,来实现框架与应用程序之间的松耦合,是两者之间协作常用的模式。
典型模式
Template Method
Strategy
Observer/Even
2. 策略模式的动机
在软件构建过程中,某些对象使用的算法可能多种多样,经常改动,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。
如何在运行时根据需要透明的更改对象的算法?如何将算法与对象本身解耦,从而避免上述问题?
3.代码
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)          //新加, 违背了开放封闭原则,对扩展开放,对更改封闭。
		{
			//FR...
		}
		//...
	}
};
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
{
public:
	virtual double Calculate(const Context& context)
	{
		//...
	}
};
class DETax :public TaxStrategy
{
public:
	virtual double Calculate(const Context& context)
	{
		//...
	}
};
//新加    符合开放封闭原则,对扩展开放,对更改封闭。
//实际上这部分新添加的代码完全可以编译成dll的方式提供使用。
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;
		this->strategy = nullptr;
	}
public:
	double CalculateTax()
	{
		//...
		Context context();
		double val = strategy->Calculate(context);    //多态调用
		//...
	}
};
5. 设计模式中讲的复用性是二进制级别的复用性。并不是源代码片段级的复用。
6.Strategy模式定义
定义一些列的算法,把他们一个个封装起来,并且使他们可以互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。
7.结构

8. 要点总结
strategy及其子类为组件提供了一系列可重用的算法,从而可以使的类型在运行时方便的根据需要在各个算法之间进行切换。
strategy模式提供了用条件判断语句以外的另外一种选择,消除了条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常需要Strategy模式。
如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。
posted on 2021-12-03 07:54 xcxfury001 阅读(51) 评论(0) 收藏 举报
 
                    
                     
                    
                 
                    
                 
                
            
         
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号