策略模式(Strategy Pattern)
概念
定义算法家族,分别封装起来,让它们之间可以互相替换,让算法变化,不会影响到用户。
模式结构
模式实例与解析
这里的例子还是上文简单工厂模式中的计算器加减乘除的设计。
与原先的简单工厂模式比较,这里提供了一个类Context,在主函数中判断是哪一算法。
#include <iostream>
using namespace std;
class Operation
{
public:
virtual double GetResult()
{
double dResult = 0;
return dResult;
}
public:
int m_nFirst;
int m_nSecond;
};
class AddOperation : public Operation
{
public:
AddOperation(int a, int b)
{
m_nFirst = a;
m_nSecond = b;
}
virtual double GetResult()
{
return m_nFirst + m_nSecond;
}
};
class SubOperation : public Operation
{
public:
SubOperation(int a, int b)
{
m_nFirst = a;
m_nSecond = b;
}
virtual double GetResult()
{
return m_nFirst - m_nSecond;
}
};
class Context
{
public:
Context(Operation * temp)
{
op = temp;
}
double GetResult()
{
return op->GetResult();
}
private:
Operation * op;
};
int main()
{
int a, b;
char c;
cin >> a >> b;
cout << "plz input operator:" << endl;
cin >> c;
switch(c)
{
Context * context;
case '+':
context = new Context(new AddOperation(a, b));
cout << context->GetResult() << endl;
break;
case '-':
context = new Context(new SubOperation(a, b));
cout << context->GetResult() << endl;
break;
}
}
优缺点
策略模式是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理变化的可能性。
在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。
优点:适合类中的成员以方法为主,算法经常变动;简化了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试)
策略模式和简单工厂基本相同,但简单工厂模式只能解决对象创建问题,对于经常变动的算法应使用策略模式。
缺点:客户端要做出判断是哪一个算法,为了将这部分判断移走,可以和简单工厂模式结合。
策略模式与简单工厂结合
修改部分,其余不变:
class Context
{
public:
Context(char cType)
{
switch(cType)
{
case '+':
op = new AddOperation(3, 8);
break;
case '-':
op = new SubOperation(5, 2);
break;
}
}
double GetResult()
{
return op->GetResult();
}
private:
Operation * op;
};
int main()
{
Context * test = new Context('+');
cout << test->GetResult() << endl;
return 0;
}
小结
我们再来比较简单工厂和结合模式两种的客户端代码:
工厂模式:
Operation * op = CalculatorFactory::Create('+');
double result = op->GetResult();
结合模式:
Context * test = new Context('+');
cout << test->GetResult() << endl;
在结合模式中对于客户端来说只需要知道有Context类就行了,降低了耦合度。
参考:
- 《大话设计模式》 程杰