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

转自:https://www.jb51.net/article/55998.htm

前言

刚刚加班回来;哎,公司规定平时加班只有10块钱的餐补;星期六和星期天加班,只给串休假;在国家规定的节假日按照3倍工资发放。那么对于这么多的计算加班费的方法,公司的OA系统是如何进行做的呢?这就要说到今天我这里总结的策略设计模式了。

策略模式

在GOF的《设计模式:可复用面向对象软件的基础》一书中对策略模式是这样说的:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。该模式使得算法可独立于使用它的客户而变化。

策略模式为了适应不同的需求,只把变化点封装了,这个变化点就是实现不同需求的算法,但是,用户需要知道各种算法的具体情况。就像上面的加班工资,不同的加班情况,有不同的算法。我们不能在程序中将计算工资的算法进行硬编码,而是能自由的变化的。这就是策略模式。
在这里插入图片描述
Strategy:定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法;
ConcreteStrategy:实现Strategy接口的具体算法;
Context:使用一个ConcreteStrategy对象来配置;维护一个对Stategy对象的引用,同时,可以定义一个接口来让Stategy访问它的数据。

使用场合

当存在以下情况时使用Strategy模式:

1.许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法;
2.需要使用一个算法的不同变体;
3.算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构;
4.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以替代这些条件语句。(是不是和状态模式有点一样哦?)
代码实现
首先实现最单纯的策略模式,代码如下:

#include <iostream>
using namespace std;

class Strategy
{
public:
	virtual void AlgorithmInterface() = 0;
};

class ConcreteStrategyA : public Strategy
{
public:
	void AlgorithmInterface()
	{
		cout << "I am from ConcreteStrategyA." << endl;
	}
};

class ConcreteStrategyB :public Strategy
{
public:
	void AlgorithmInterface()
	{
		cout << "I am from ConcreteStrategyB." << endl;
	}
};

class ConcreteStrategyC : public Strategy
{
public:
	void AlgorithmInterface()
	{
		cout << "I am from ConcreteStrategyC." << endl;
	}
};

class Context
{
public:
	Context(Strategy *pStrategyArg) : pStragegy(pStrategyArg)
	{}

	void ConcreteInterface()
	{
		pStragegy->AlgorithmInterface();
	}
private:
	Strategy *pStragegy;
};

int main()
{
	Strategy *pStrategyA = new ConcreteStrategyA();
	Strategy *pStrategyB = new ConcreteStrategyB();
	Strategy *pStrategyC = new ConcreteStrategyC();

	Context *pContextA = new Context(pStrategyA);
	Context *pContextB = new Context(pStrategyB);
	Context *pContextC = new Context(pStrategyC);

	pContextA->ConcreteInterface();
	pContextB->ConcreteInterface();
	pContextC->ConcreteInterface();

	if (pStrategyA)
		delete pStrategyA;

	if (pStrategyB)
		delete pStrategyB;

	if (pStrategyC)
		delete pStrategyC;

	if (pContextA)
		delete pContextA;

	if (pContextB)
		delete pContextB;

	if (pContextC)
		delete pContextC;
}

运行结果:
在这里插入图片描述
在实际操作的过程中,我们会发现,在main函数中,也就是在客户端使用策略模式时,会创建非常多的Strategy,而这样就莫名的增加了客户端的压力,让客户端的复杂度陡然增加了。那么,我们就可以借鉴简单工厂模式,使策略模式和简单工厂模式相结合,从而减轻客户端的压力,代码实现如下:

#include <iostream>
using namespace std;

typedef enum StrategyType
{
	StrategyA,
	StrategyB,
	StrategyC
}STRATEGYTYPE;

class Strategy
{
public:
	virtual void AlgorithmInterface() = 0;
	virtual ~Strategy() = 0;
};

Strategy::~Strategy() {}

class ConcreteStrategyA : public Strategy
{
public:
	void AlgorithmInterface()
	{
		cout << "I am from ConcreteStrategyA." << endl;
	}
	~ConcreteStrategyA() {}
};

class ConcreteStrategyB :public Strategy
{
public:
	void AlgorithmInterface()
	{
		cout << "I am from ConcreteStrategyB." << endl;
	}
	~ConcreteStrategyB() {}
};

class ConcreteStrategyC : public Strategy
{
public:
	void AlgorithmInterface()
	{
		cout << "I am from ConcreteStrategyC." << endl;
	}
	~ConcreteStrategyC() {}
};

class Context
{
public:
	Context(STRATEGYTYPE strategyType)
	{
		switch (strategyType)
		{
		case StrategyA:
			pStragegy = new ConcreteStrategyA;
			break;

		case StrategyB:
			pStragegy = new ConcreteStrategyB;
			break;

		case StrategyC:
			pStragegy = new ConcreteStrategyC;
			break;

		default:
			break;
		}
	}

	~Context()
	{
		if (pStragegy)
		{
			delete pStragegy;
		}
	}

	void ContextInterface()
	{
		if (pStragegy)
		{
			pStragegy->AlgorithmInterface();
		}
	}

private:
	Strategy *pStragegy;
};

int main()
{
	Context *pContext = new Context(StrategyA);
	pContext->ContextInterface();

	if (pContext)
	{
		delete pContext;
	}
	return 0;
}

在这里插入图片描述
在上面这个代码中,其实,我们可能看到的更多的是简单工厂模式的应用,我们将策略模式将简单工厂模式结合在了一起,让客户端使用起来更轻松。

总结

策略模式和状态模式,是大同小异的;状态模式讲究的是状态的变化,和不同状态下,执行的不同行为;而策略模式侧重于同一个动作,实现该行为的算法的不同,不同的策略封装了不同的算法。策略模式适用于实现某一功能,而实现该功能的算法是经常改变的情况。在实际工作中,遇到了实际的场景,可能会有更深的体会。比如,我们做某一个系统,该系统可以适用于各种数据库,我们都知道,连接某一种数据库的方式是不一样的,也可以说,连接数据库的“算法”都是不一样的。这样,我们就可以使用策略模式来实现不同的连接数据库的策略,从而实现数据库的动态变换。

转自:https://www.jb51.net/article/55998.htm

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值