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

策略模式封装了算法家族,允许在不修改原有代码的情况下切换算法,降低了类间的耦合。它遵循开放-封闭原则,方便扩展。与简单工厂模式结合,常用于处理多变的算法需求。策略模式简化了单元测试,并减少了代码中的条件判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计模式之策略模式

策略模式定义算法家族,分别封装。它们之间可以相互替换,让算法变化,不会影响到用户。优点:适合类中的成员方法为主,算法经常变动;简单了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试)。缺点:客户端需要做出判断。

其UML图如下:

策略模式UML图

策略模式和简单工厂模式非常相似。具体来讲有个细微的区别就是,简单工厂模式需要根据传递过来的条件判断创建什么样的对象。而策略模式是直接传递给Context一个对象,至于传递什么类型的对象则是需要用户自己去判断。从这一点来讲策略模式遵从了开放-封闭原则,当需要添加不同的算法的时候只需要添加一个算法类就可以了,并不用去修改Context类。而简单工厂模式则破坏了开放-封闭原则,当需要添加不同的对象时候,不仅需要添加响应的类,还需要修改工厂类。这一点无所谓好与坏,主要还是看需求。这两种模式也经常结合起来使用,因为策略模式需要根据需求判断生成算法类对象,而这一部分可以封装成一个简单工厂模式。另一方面,简单工厂模式主要解决的是对象创建问题,而策略模式主要解决的是经常变动算法的问题。

策略模式与简单工厂模式相结合给出的四则运算的示例代码如下:

// StrategyModel.h文件
#pragma once
// 操作基类
template<typename T>
class Operation
{
public:
	Operation(T lpa, T rpa);
	virtual T getResult() = 0;
protected:
	T lpa, rpa;
};

template<typename T>
Operation<T>::Operation(T lpa, T rpa)
{
	this->lpa = lpa;
	this->rpa = rpa;
}
// 加法类
template<typename T>
class AddOperation : public Operation<T>
{
public:
	AddOperation(T lpa, T rpa) : Operation<T>(lpa, rpa){}
	T getResult()
	{
		return this->lpa + this->rpa;
	}
};
// 减法类
template<typename T>
class SubOperation : public Operation<T>
{
public:
	SubOperation(T lpa, T rpa) : Operation<T>(lpa, rpa) {}
	T getResult()
	{
		return this->lpa - this->rpa;
	}
};
// 乘法类
template<typename T>
class MulOperation : public Operation<T>
{
public:
	MulOperation(T lpa, T rpa) : Operation<T>(lpa, rpa) {}
	T getResult()
	{
		return this->lpa * this->rpa;
	}
};
// 除法类
template<typename T>
class DivOperation : public Operation<T>
{
public:
	DivOperation(T lpa, T rpa) : Operation<T>(lpa, rpa) {}
	T getResult()
	{
		if (0 == this->rpa)
		{
			std::cout << "除数不能为0" << std::endl;
			return 0;
		}
		return this->lpa / this->rpa;
	}
};
// context类
template<typename T>
class Context
{
public:
	Context(Operation<T> * p)
	{
		m_Operator = p;
	}
	~Context()
	{
		if (nullptr != m_Operator)
			delete m_Operator;
	}
	void getResult()
	{
		std::cout << m_Operator->getResult() << std::endl;
	}
private:
	Operation<T> * m_Operator;
};

// 和简单工厂模式结合
template<typename T>
class Factory
{
public:
	Factory(): m_operator(nullptr) {}
	~Factory() {
		if (nullptr == m_operator)
			delete m_operator;
		m_operator = nullptr;
	}
	static Operation<T> * createObject(T lpa, T rpa, char c);
};

template<typename T>
Operation<T> * Factory<T>::createObject(T lpa, T rpa, char c)
{
	Operation<T> * m_operator;
	switch (c)
	{
	case '+':
		m_operator = new AddOperation<T>(lpa, rpa);
		break;
	case '-':
		m_operator = new SubOperation<T>(lpa, rpa);
		break;
	case '*':
		m_operator = new MulOperation<T>(lpa, rpa);
		break;
	case '/':
		m_operator = new DivOperation<T>(lpa, rpa);
	default:
		m_operator = new AddOperation<T>(lpa, rpa);
		break;
	}
	return m_operator;
}

测试代码如下:

#include <iostream>
#include "StrategyModel.h"

int main()
{
	using namespace std;
	// 策略模式,和工厂模式结合
	Context<double> * p = new Context<double>(Factory<double>::createObject(132.321, 142.32, '+'));
	p->getResult();
	delete p;

	p = new Context<double>(Factory<double>::createObject(132.321, 142.32, '-'));
	p->getResult();
	delete p;
	
	p = new Context<double>(Factory<double>::createObject(132.321, 142.32, '*'));
	p->getResult();
	delete p;

	p = new Context<double>(Factory<double>::createObject(132.321, 142.32, '/'));
	p->getResult();
	delete p;

	getchar();
	return 0;
}

其输出结果如下:
在这里插入图片描述

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以相同的方式调用所有的算法,减少了各种算法类与使用类之间的耦合。策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法种的公共功能。另外一个优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。也就是说在基本的策略模式中,选择所具体实现的职责有客户端对象承担了,并转给策略模式的Context对象。

策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值