您的位置:首页 > 其它

Strategy 策略模式

2016-07-15 14:51 399 查看

意图

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

动机

策略模式为了适应不同的需求,只把变化点封装了,这个变化点就是实现不同需求的算法,但是,用户需要知道各种算法的具体情况。就像上面的加班工资,不同的加班情况,有不同的算法。我们不能在程序中将计算工资的算法进行硬编码,而是能自由的变化的。这就是策略模式。

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

适用性

许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。

需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式

算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。

一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

结构



参与者

Strategy:定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法;
ConcreteStrategy:实现Strategy接口的具体算法;
Context:使用一个ConcreteStrategy对象来配置;维护一个对Stategy对象的引用,同时,可以定义一个接口来让Stategy访问它的数据。

效果

相关算法系列Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。

实现

纯策略模式,实际上就是父类为纯虚函数,子类根据需求实现各种方法

#include <iostream>
using namespace std;

// The abstract strategy
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) : pStrategy(pStrategyArg)
{
}
void ContextInterface()
{
pStrategy->AlgorithmInterface();
}
private:
Strategy *pStrategy;
};

int main()
{
// Create the Strategy
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->ContextInterface();
pContextB->ContextInterface();
pContextC->ContextInterface();

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;

// Define the strategy type
typedef enum StrategyType
{
StrategyA,
StrategyB,
StrategyC
}STRATEGYTYPE;

// The abstract strategy
class Strategy
{
public:
virtual void AlgorithmInterface() = 0;
virtual ~Strategy() = 0; // 谢谢hellowei提出的bug,具体可以参见评论
};

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:
pStrategy = new ConcreteStrategyA;
break;

case StrategyB:
pStrategy = new ConcreteStrategyB;
break;

case StrategyC:
pStrategy = new ConcreteStrategyC;
break;

default:
break;
}
}

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

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

private:
Strategy *pStrategy;
};

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

if (pContext) delete pContext;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: