策略模式
定义一系列的算法,把他们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。属于行为型模式。

适用场景
1、许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
2、需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式。
3、 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
4、一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的 Strategy类中以代替这些条件语句。

优缺点 

优点:策略模式把算法进行归纳,使得算法的切换、扩展更加容易。

缺点:策略使用者需要了解各个具体策略,使得整个模式的封装性不强。

UML图

Strategy Pattern

环境类(Context): 内部维护一个Strategy对象的引用,对外提供相应功能接口;

策略类(Strategy): 定义算法的一个或多个接口;

具体策略类(ConcreteStrategy): 实现Strategy定义的接口,提供具体算法的实现;

代码实现

Strategy.h

#pragma once

// 抽象策略
class Strategy
{
public:
	Strategy() {};
	virtual ~Strategy() {};

	virtual void AlgorithmInterface(double num1, double num2) = 0;
};

// 加法
class StrategyAdd : public Strategy
{
public:
	void AlgorithmInterface(double num1, double num2);
};
// 减法
class StrategySubstract : public Strategy
{
public:
	void AlgorithmInterface(double num1, double num2);
};
// 乘法
class StrategyMultiply : public Strategy
{
public:
	void AlgorithmInterface(double num1, double num2);
};
// 除法
class StrategyDivide : public Strategy
{
public:
	void AlgorithmInterface(double num1, double num2);
};

Strategy.cpp

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

void StrategyAdd::AlgorithmInterface(double num1, double num2)
{
	std::cout << num1 << " + " << num2 << " = " << num1 + num2 << std::endl;
}

void StrategySubstract::AlgorithmInterface(double num1, double num2)
{
	std::cout << num1 << " - " << num2 << " = " << num1 - num2 << std::endl;
}

void StrategyMultiply::AlgorithmInterface(double num1, double num2)
{
	std::cout << num1 << " × " << num2 << " = " << num1 * num2 << std::endl;
}

void StrategyDivide::AlgorithmInterface(double num1, double num2)
{
	std::cout << num1 << " ÷ " << num2 << " = " << num1 / num2 << std::endl;
}

Context.h

#pragma once

class Strategy;

class Context
{
public:
	Context(Strategy *pStrategyArg) : m_pStrategy(pStrategyArg) {}
	void ContextInterface(double num1, double num2);

private:
	Strategy *m_pStrategy = nullptr;
};

Context.cpp

#include "Context.h"
#include "Strategy.h"

void Context::ContextInterface(double num1, double num2)
{
	m_pStrategy->AlgorithmInterface(num1, num2);
}

main.cpp

#include "Strategy.h"
#include "Context.h"
#include <process.h>

int main()
{
	auto pStrategyAdd = new StrategyAdd;
	auto pStrategySubstract = new StrategySubstract;
	auto pStrategyMultiply = new StrategyMultiply;
	auto pStrategyDivide = new StrategyDivide;

	auto pContextA = new Context(pStrategyAdd);
	auto pContextB = new Context(pStrategySubstract);
	auto pContextC = new Context(pStrategyMultiply);
	auto pContextD = new Context(pStrategyDivide);

	pContextA->ContextInterface(1.23, 4.56);
	pContextB->ContextInterface(1.23, 4.56);
	pContextC->ContextInterface(1.23, 4.56);
	pContextD->ContextInterface(1.23, 4.56);

	if (pStrategyAdd) delete pStrategyAdd;
	if (pStrategySubstract) delete pStrategySubstract;
	if (pStrategyMultiply) delete pStrategyMultiply;
	if (pStrategyDivide) delete pStrategyDivide;

	if (pContextA) delete pContextA;
	if (pContextB) delete pContextB;
	if (pContextC) delete pContextC;
	if (pContextD) delete pContextD;

	system("pause");

	return 0;
}

输出

总结

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


版权声明:本文为YWJ_2011原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/YWJ_2011/article/details/116530296