首页 > 编程语言 >设计模式C++002__策略模式

设计模式C++002__策略模式

时间:2024-07-25 19:20:37浏览次数:10  
标签:__ double Tax C++ TaxStrategy 算法 context 设计模式 public

设计模式C++002__策略模式

1、动机:

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

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

2、策略模式:

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

例如跨国电商公司,订单计算税费的功能。
前期只有3个国家的业务,就只定义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){  //更改
			//...
		}

        //....
     }
    
};

如果使用策略模式,定义一个税费计算抽象基类,基类中只有一个计算税费的虚方法,不同国家的税费计算方法继承自抽象基类,各自实现自己的税费计算方法。
如果要支持新的税费计算方法,只需新建一个子类,根据实际情况实现即可。调用时利用C++的多态性质,在主函数中父类的指针指向子类对象,再用指针调用计算税费方法。
理论上,只要是if-else, switch-case 中可能会扩展新的分支以支持业务。都可以改为策略模式。

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;  //这里声明一个虚基类指针,访问类型为private

public:
    SalesOrder(StrategyFactory* strategyFactory){
        this->strategy = strategyFactory->New Strategy();//这里就是子类实例对象的产生的地方,可能是一个工厂方法产生的。
    }
    ~SalesOrder(){
        delete this->strategy;
    }

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

3、策略模式相比 if-else这种分支处理。可以在不改变原有类的基础上,只新增子类,就可以实现对原有功能的扩展。符合开闭原则。

实际上,这也是利用了晚绑定的原理,调用哪一种方法。
结构:

4、要点总结:

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

标签:__,double,Tax,C++,TaxStrategy,算法,context,设计模式,public
From: https://www.cnblogs.com/wjw-blog/p/18312167

相关文章

  • 设计模式C++003__观察者模式
    设计模式C++003__观察者模式1、动机:在软件构建过程中,我们需要为某些对象建立一种“通过依赖关系”--一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使得软件不好抵御变化。?使用面向对象技术,可以将这种依赖关系弱化,并形成......
  • NOIP2024/7/25模拟赛
    T4题意:答案对\(2^{16}\)取模。分析:根节点\(1\)选到\(1\)的概率为\(\frac{1}{n}\),然后随便把剩下的\(n-1\)分配给它的所有子树,记\(1\)的其中一个儿子为\(y\),那么\(y\)选到它所被分配到的数中最小值的概率为\(\frac{1}{siz_{y}}\),然后\(y\)再继续分配给它的子......
  • 关键字和保留字
    关键字定义:是被java赋予了特定含义的英文单词特点:所有字母都小写注意:java中的null不是关键字,和true、false类似,它是一个字面常量,不能作为标识符来进行使用具体可以参考官网:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html初学时并不需要一次性记......
  • python实现ftpServer
    使用python模拟一个fetServer importosimportsocketimportthreadingfrompyftpdlib.authorizersimportDummyAuthorizerfrompyftpdlib.handlersimportFTPHandlerfrompyftpdlib.serversimportFTPServer_source_root=os.path.dirname(os.path.dirname(os.path......
  • python处理process(windows)
    python根据进程名称获取进程id、taskkill进程 importosimportpsutilfrompsutilimportNoSuchProcessclassProcessUtilCls:#停止进程(windows)。#参数:tag=1时按照process_name停止进程,否则按照pids[pid1,pid2...]停止进程@staticmethoddefpr......
  • 国资央企招聘平台的招聘信息爬取
    前言国资央企招聘平台集成了众多国企央企的招聘。写一个脚本实现一下各个岗位的招聘接口当抓包的时候发现,这些岗位信息都是通过接口发布的。因此可以通过获取这个接口的数据爬取。编写代码:'''基于国资央企招聘平台的招聘信息。https://cujiuye.iguopin.com/'''import......
  • 设计模式C++004__装饰器模式
    设计模式C++004__装饰器模式在软件组件设计中,如果职责划分不清晰,使用继承得到的结果往往会随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候关键是划清责任。单一职责模式分类中的设计模式:装饰器模式,桥模式1、装饰器模式:动机:在某些情况下,我们可能会“过渡地使用继承来扩......
  • 设计模式C++005__桥模式
    设计模式C++005__桥模式也是组合模式的具体体现。1、动机:由于某些类型的古有的实现逻辑,使得他们具有两个变化的维度,乃至多个维度的变化。?如何应对这种“多维度的变化”,如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度。2、桥模式:将......
  • 河南萌新联赛2024第(二)场:南阳理工学院
    1.D-A*BBBB原题链接:https://ac.nowcoder.com/acm/contest/87255/D根据乘法的原理,且b的每一位都相同,最终答案则是错位相加得出的结果,于是我们将a翻转,从个位开始计算,如果当前位置小于a.size就往前累加,但如果大于或等于b.size就从头开始一个一个的减(这个过程可以通过纸上手写乘法计......
  • 设计模式C++007__抽象工厂方法模式
    设计模式C++007__抽象工厂方法模式抽象工厂方法1、动机:在软件系统重,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。?如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种封装机制,来避免客户程序和这种“多系列具体对象......