策略模式,又称strategy模式,是用于封装多样性的算法,避免支持不使用的算法带来的性能负担。

定义

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

动机

在软件系统中,常常会遇到许多算法可以实现同一功能的情况,可以将这些算法写到一个类中,通过if…else来判断和选择,如果需要增加一种算法,则需要修改代码,增加分支,违背了设计模式的封闭原则

更好的方法是将这些算法分别写在单独的类中,在客户端中使用这些算法子类的抽象接口,在运行时使用多态来决定具体使用哪一个算法。

模式结构

  • Strategy : 算法的抽象接口
  • ConcreteStrategy A/B/C : 具体的不同的算法
  • Context : 算法使用的上下文

代码分析

例子程序使用策略模式实现了一个加减乘除的计算功能。

算法抽象接口

class Calculate
{
public:
	virtual ~Calculate();
	virtual float calculate(float a , float b) = 0;
};

不同的算法子类

class Add : public Calculate
{
public:
	Add();
	~Add();

	float calculate(float a, float b);
};
float Add::calculate(float a, float b)
{
	return (a + b);
}

class Sub : public Calculate
{
public:
	Sub();
	~Sub();

	float calculate(float a, float b);
};
float Sub::calculate(float a, float b)
{
	return (a - b);
}

class Mul : public Calculate
{
public:
	Mul();
	~Mul();

	float calculate(float a, float b);
};
float Mul::calculate(float a, float b)
{
	return (a * b);
}

class Div : public Calculate
{
public:
	Div();
	~Div();

	float calculate(float a, float b);
};
float Div::calculate(float a, float b)
{
	return (a / b);
}

使用算法的上下文

class CalOrder
{
public:
	CalOrder(Calculate *Cal, int a, int b);
	~CalOrder();

private:
	Calculate *p_Cal;
	int data1;
	int data2;

public:
	float calculate();
	
};

CalOrder::CalOrder (Calculate *Cal, int a, int b)
{
	this->p_Cal = Cal;
	this->data1 = a;
	this->data2 = b;
}

CalOrder::~CalOrder()
{
}

float CalOrder::calculate()
{
	return this->p_Cal->calculate(this->data1, this->data2);
}

main函数测试
定义了一个具体的算法,和使用算法的上下文。

int main()
{
	Calculate *cal = new Add;
	CalOrder *caloder = new CalOrder(cal, 1, 2);
	std::cout << "ADD : " << caloder->calculate() << std::endl;
}

结果:

策略模式属于组件协作模式的一种,基本思想是通过框架和应用程序的晚期绑定(手段:虚函数),实现框架和应用之间的松耦合。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

抽象工厂 上一篇
工厂模式 下一篇