Strategy模式和State模式比较相似,在技术上都使用了委托,但从语义上,State模式把状态作为对象,
描述一个类在运行时的状态变化;Strategy模式则是把一个算法当作一个对象,达到在运行时自由替换算法的目的。他们在结构上的不同在于State模 式通常有一个Context的引用(例如在我的State模式中,Context就是TrafficLight,但我在这个例子里没包含这个引用,因为例 子太简单而没必要),在适当的时候State对象可以回调这个Context的引用,而Strategy没有这个引用。
我们现在使用Strategy模式来模拟我们在编程时的出错提示。试想:我们的程序在出错的时候,可能想把错误的原因提示给 用户看,但是有时候我们又想把错误记录在LOG里,用户不用关心,这对于错误提示来说就是两种算法。
下面看看模拟的代码:
#include
<
iostream
>
#include < string >
using namespace std;
// 先定义一个接口
class Strategy
{
public:
virtual void Output(string s) = 0;
} ;
class ShowStrategy : public Strategy
{
public:
virtual void Output(string s)
{
// 这里用输出字串来模拟,但在实际的项目中可能就是MessageBox之类的函数了
cout << "Show Strategy!! Error: " << s << endl;
}
} ;
class LogStrategy : public Strategy
{
public:
virtual void Output(string s)
{
// 这里用输出字串来模拟,但在实际的项目中可能就是打开文件,然后写log记录了
cout << "Log Strategy!! Error: " << s << endl;
}
} ;
// 一个使用Strategy的上下文类Context
class Context
{
public:
void SetStrategy(Strategy *s)
{
_s = s;
}
// 功能函数,现实中可能是一个完成实际功能的函数
void Function()
{
// 调用一些其他的函数
// 例如,OpenFile之类的
// 如果出错了,就Output错误
_s->Output("OpenFile failed!");
}
private:
Strategy *_s;
} ;
void main()
{
Context c;
ShowStrategy ss;
LogStrategy ls;
// 使用ShowStrategy弹出对话框
c.SetStrategy(&ss);
c.Function();
// 使用LogStrategy记录错误日志
c.SetStrategy(&ls);
c.Function();
}
#include < string >
using namespace std;
// 先定义一个接口
class Strategy
{
public:
virtual void Output(string s) = 0;
} ;
class ShowStrategy : public Strategy
{
public:
virtual void Output(string s)
{
// 这里用输出字串来模拟,但在实际的项目中可能就是MessageBox之类的函数了
cout << "Show Strategy!! Error: " << s << endl;
}
} ;
class LogStrategy : public Strategy
{
public:
virtual void Output(string s)
{
// 这里用输出字串来模拟,但在实际的项目中可能就是打开文件,然后写log记录了
cout << "Log Strategy!! Error: " << s << endl;
}
} ;
// 一个使用Strategy的上下文类Context
class Context
{
public:
void SetStrategy(Strategy *s)
{
_s = s;
}
// 功能函数,现实中可能是一个完成实际功能的函数
void Function()
{
// 调用一些其他的函数
// 例如,OpenFile之类的
// 如果出错了,就Output错误
_s->Output("OpenFile failed!");
}
private:
Strategy *_s;
} ;
void main()
{
Context c;
ShowStrategy ss;
LogStrategy ls;
// 使用ShowStrategy弹出对话框
c.SetStrategy(&ss);
c.Function();
// 使用LogStrategy记录错误日志
c.SetStrategy(&ls);
c.Function();
}
最后再说一下,Strategy和State模式的架构基本相同,他们的核心思想也就是用了委托技术。
事实上,设计模式也就是巧妙的使用面向对象的各种特性来组合对象间的关系的,这些特性包括:
组合、多态、封装、继承、委托等。
所以搞明白面向对象的这些特性,就是设计模式的基础!