学习笔记——C++设计模式之策略模式

C++设计模式之策略模式

_学习B站李建忠老师课程记录

动机:

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

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

模式定义:

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

重构前代码 税率计算举例:

#include <iostream>
#include<vector>
using namespace std;
enum TaxBase
{
	CN_Tax = 0,
	US_Tax = 1,
	DE_Tax = 2,
	FR_Tax = 3
};
class SaleOrder {
private:
	TaxBase m_tax;
public:
	SaleOrder(TaxBase tax):m_tax(tax){ }
	~SaleOrder(){}
public:
	double CalculateTax() {
		if (m_tax == CN_Tax) {
			//CN.........
		}
		else if (m_tax == US_Tax) {
			//US......
		}
		else if (m_tax == DE_Tax) {
			//DE...........
		}
		else if (m_tax == FR_Tax) {
			//FE.........
		}
		return 0;
	}
};

int main() {
	
	SaleOrder myorder(TaxBase::FR_Tax);
	double tax=myorder.CalculateTax();
	cout << tax << endl;
	return 0;
}

问题思考:

如果加新西兰等等税法,需要更改的函数,添加诸多的if else语句 。

double CalculateTax() {}

重构后代码:

#include <iostream>
using namespace std;
class TaxStrategy {//税率的策略基类 为纯虚基类 抽象类
public:
	virtual double Calculate(const Context& context) = 0;
	virtual ~TaxStrategy(){}//基类一定要把基类的析构函数声明为virtual
};
// 添加扩展1:中国税率
class CN_Tax :public TaxStrategy {
public:
	virtual double Calculate(const Context& context) {
		// Override:实现China税率的计算方法
		return 0;
	}
};
// 添加扩展2:美国税率
class US_Tax :public TaxStrategy {
public:
	virtual double Calculate(const Context& context) {
		// Override:实现US_Tax税率的计算方法
		return 0;
	}
};
// 添加扩展2:法国税率
class FR_Tax :public TaxStrategy {
public:
	virtual double Calculate(const Context& context) {
		// Override:实现法国税率的计算方法
		return 0;
	}
};
//可以添加任意国家的税率计算方法 ,SaleOrder方法不变

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); //动态联编 多态调用 什么国家调用什么税法计算方法
		return val;
		//...
	}
};


int main() {
	
	StrategyFactory* strategy_factory;
	SalesOrder saleorder(strategy_factory);//调用构造函数传参
	double tax=saleorder.CalculateTax();
	cout << tax << endl;

	return 0;
}

要点总结

1.如果出现if else的分类绝对不会变,可以不采用策略模式;如果从时间轴发展的角度,一个程序代码可能在未来扩展。
2.Strategy及子类为组件提供了一些列可重用的算法,从而使得类型在运行时方便根据需要在各算法之间切换。

3.策略模式提供了用条件判断语句以外的一种可扩展的选择,消除条件判断语句,就是在解耦合,含有许多条件判断语句代码通常都需要策略模式;
4.如果策略对象没有实例变量,那么各个上下文可以共享一个策略对象,从而节省对象开销.

tips:运行时候最好加载到CPU的高级缓存里,如果代码段过长,需要放到主存里,甚至放在虚拟内存/硬盘里,一些代码不真正使用却装载到CPU高级缓存里,其他代码可能不能放在高级缓存里,影响运行效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值