Strategy-策略模式
税务计算
根据不同国家的税率进行不同算法计算
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){
//更改//...}//....}};
考虑未来变化,当出现新的需求(新的国家增加),需要考虑实现enum增加新的税法如法国,并在if else的控制语句下新增新的计算方法。
此种设计并不是正确,违背开闭原则,也不是代码复用,应该应可能使用扩展的方式。
使用Strategy设计模式重构代码。
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); //多态调用//...}};
TaxStrategy是抽象基类,实现税率计算的抽象接口,并同时具有虚析构函数。
由各国税法继承TaxStrategy,并实现不同的税率计算。新的需求出现时,可以直接将法国税率类继承TaxStrategy,并实现法国的税率计算功能。
SalesOrder类组合方式包含税率基类指针,实际是多态指针,构造器借由工厂类实现产生不同的派生类指针去实现其独有的税率计算,工厂类返回的是堆对象,而不是栈对象,所以需要析构前delete。
Context context();负责构建上下文环境。
未使用Strategy设计模式的缺陷是,代码得不到二进制层面复用,通过更改源码来实现添加往往会打破前面的条件,产生问题。计算机在运行时,大量不被使用的代码段被装载,但实际使用的只是某种税率计算。最好的运行模式是将代码段装载在CPU高级缓存中,但if else或switch case的结构设计会导致代码过多,实际真正执行代码段可能放不进CPU高级缓存中。
Strategy设计模式可以解决这个性能问题,节省对象开销,并利于功能扩展,符合开闭原则,对扩展开放,对更改封闭。
出自C++设计模式