策略和职责链模式: 运行时选择的算法。
策略模式的主要意图是: 对于一个问题,我们其实可以通过多种方式来解决,但最好的解决方式都是根据"具体的情况"来决定的。这就是动态的选择,是策略。 职责链是将一系列的策略串在一起,当遇到问题时从头到尾对职责链进行遍历,来找到最适合的解决方式。
这里的"具体情况"在程序中可以理解为上下文环境 context,它的输入会决定到底采取什么样的策略。
如果用UML图表示的话,策略模式与命令模式或状态模式会有些接近,所以理解它解决问题的思路和意图会更加实用。
示例程序 <来自 Thingking in C++>
场景: 假如忘了一个人的名字怎么办? 策略模式
场景: 一个小孩想和家人要礼物,他会和妈妈,爸爸,爷爷,奶奶挨个要,看看谁会满足他。 职责链模式
策略模式的主要意图是: 对于一个问题,我们其实可以通过多种方式来解决,但最好的解决方式都是根据"具体的情况"来决定的。这就是动态的选择,是策略。 职责链是将一系列的策略串在一起,当遇到问题时从头到尾对职责链进行遍历,来找到最适合的解决方式。
这里的"具体情况"在程序中可以理解为上下文环境 context,它的输入会决定到底采取什么样的策略。
如果用UML图表示的话,策略模式与命令模式或状态模式会有些接近,所以理解它解决问题的思路和意图会更加实用。
示例程序 <来自 Thingking in C++>
场景: 假如忘了一个人的名字怎么办? 策略模式
#include <iostream>
using namespace std;
class NameStrategy
{
public:
virtual void greet() = 0;
};
class SayHi : public NameStrategy
{
public:
void greet() {cout << "Hi, how are you" << endl;}
};
class SaySorry : public NameStrategy
{
public:
void greet() {cout << "Sorry, I forget your name" << endl;}
};
class Ignore : public NameStrategy
{
public:
void greet() {cout << "Pretend, I didn't see you" << endl;}
};
class Context
{
private:
NameStrategy& m_NameStrategy;
public:
Context(NameStrategy& s) : m_NameStrategy(s){};
void greet() {m_NameStrategy.greet();};
};
void main()
{
int i = 0;
SayHi sayhi;
SaySorry saysorry;
Ignore ignore;
Context c1(sayhi), c2(saysorry), c3(ignore);
c1.greet();
c2.greet();
c3.greet();
cin >> i;
}
场景: 一个小孩想和家人要礼物,他会和妈妈,爸爸,爷爷,奶奶挨个要,看看谁会满足他。 职责链模式
#include <iostream>
#include <vector>
using namespace std;
enum ANSWER {NO, YES};
class GimmeStragegy
{
public:
virtual ANSWER mayIhave() = 0;
virtual ~GimmeStragegy() {};
};
class AskMom : public GimmeStragegy
{
public:
ANSWER mayIhave() {cout << "Mom may I have this?" << endl; return NO;}
};
class AskDad : public GimmeStragegy
{
public:
ANSWER mayIhave() {cout << "Dad may I have this?" << endl; return NO;}
};
class AskGrandpa : public GimmeStragegy
{
public:
ANSWER mayIhave() {cout << "Grandpa may I have this?" << endl; return NO;}
};
class AskGrandma : public GimmeStragegy
{
public:
ANSWER mayIhave() {cout << "Grandma may I have this?" << endl; return YES;}
};
class Gimme : public GimmeStragegy
{
private:
vector<GimmeStragegy*> m_ResponseChain;
public:
Gimme()
{
m_ResponseChain.push_back(new AskMom());
m_ResponseChain.push_back(new AskDad());
m_ResponseChain.push_back(new AskGrandpa());
m_ResponseChain.push_back(new AskGrandma());
}
ANSWER mayIhave()
{
vector<GimmeStragegy*>::iterator it = m_ResponseChain.begin();
while (it != m_ResponseChain.end())
if ((*it++)->mayIhave() == YES) return YES;
cout << "Nothing ... ..." << endl;
return NO;
}
~Gimme()
{
for (vector<GimmeStragegy *>::iterator it = m_ResponseChain.begin(); it != m_ResponseChain.end(); it ++)
if (NULL != *it)
{
delete *it;
*it = NULL;
}
m_ResponseChain.clear();
}
};
void main()
{
int i = 0;
Gimme chain;
chain.mayIhave();
cin >> i;
}