【GeekBand】C++设计模式笔记4_Strategy_策略模式

1. "组件协作"模式

  • 现代软件专业分工之后的第一个结果是"框架与应用程序的划分 ","组件协作"模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。
  • 典型模式
    • Template Method
    • Strategy
    • Observer / Event

2. Strategy 策略模式

2.1 动机(Motivation)

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

2.2 模式定义

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

------《设计模式》 GoF

2.3 实例代码

2.3.1 strategy1
cpp 复制代码
// 税率类
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) {  // 更改,条件判断语句中增加对法国税率的分支
			// ...
		}

        // ....
     }
};
2.3.2 strategy2
cpp 复制代码
// 税率基类
class TaxStrategy {
public:
    virtual double Calculate(const Context& context)=0;	// 纯虚函数
    virtual ~TaxStrategy() {}	// 基类的析构函数要声明成virtual
};

// 中国税率,继承基类,重写虚函数
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);	// 多态调用
        // ...
    }  
};

2.4 结构(Structure)

2.5 要点总结

  • Strategy及其子类为组件提供了一系列可重用的算法(ps:实例中的各个具体类),从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。
  • Strategy模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。
  • 如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。
相关推荐
天堂的恶魔9463 小时前
C++封装
java·开发语言·c++
TechNomad3 小时前
深入理解C++的new和delete
c++
阿猿收手吧!4 小时前
【CPP】CPP经典面试题
开发语言·c++·面试·协程
xianwu5435 小时前
反向代理模块anns
数据库·c++·python·mysql·django
linhhanpy5 小时前
自制虚拟机(C/C++)(一、分析语法和easyx运用,完整虚拟机实现)
c语言·汇编·c++·单片机·操作系统
半桔6 小时前
七大排序思想
c语言·开发语言·数据结构·c++·算法·排序算法
牵牛老人6 小时前
C++ 使用CURL开源库实现Http/Https的get/post请求进行字串和文件传输
c++·http·https
水饺编程7 小时前
MFC 学习笔记目录
c语言·c++·windows·visual studio
SomeB1oody7 小时前
【Rust自学】20.2. 最后的项目:多线程Web服务器
服务器·开发语言·前端·后端·设计模式·rust
fly spider7 小时前
wait/notify/join/设计模式
java·开发语言·设计模式