【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对象,从而节省对象开销。
相关推荐
Once_day26 分钟前
Linux错误(6)X64向量指令访问地址未对齐引起SIGSEGV
linux·c++·sse·x64·sigsegv·xmm0
JhonKI43 分钟前
【从零实现Json-Rpc框架】- 项目实现 - 客户端注册主题整合 及 rpc流程示意
c++·qt·网络协议·rpc·json
__lost1 小时前
为什么new分配在堆上,函数变量在栈上+递归调用时栈内存的变化过程
c++·内存分配
云徒川1 小时前
【设计模式】代理模式
设计模式·代理模式
序属秋秋秋1 小时前
算法基础_基础算法【位运算 + 离散化 + 区间合并】
c语言·c++·学习·算法·蓝桥杯
jyyyx的算法博客1 小时前
【再探图论】深入理解图论经典算法
c++·算法·图论
念_ovo2 小时前
【算法/c++】利用中序遍历和后序遍历建二叉树
数据结构·c++·算法
Vitalia2 小时前
⭐算法OJ⭐寻找最短超串【动态规划 + 状态压缩】(C++ 实现)Find the Shortest Superstring
开发语言·c++·算法·动态规划·动态压缩
Niuguangshuo2 小时前
Python 设计模式:外观模式
python·设计模式·外观模式
C-DHEnry2 小时前
迪杰斯特拉+二分+优先队列+拓扑+堆优化(奶牛航线Cowroute、架设电话线dd、路障Roadblocks、奶牛交通Traffic)
c++·算法·动态规划·二分·拓扑·堆优化·迪杰斯特拉