Strategy策略模式是在模板方法模式上的一個改進,模板方法模式是代碼復用,這里用組合來解決將變化的代碼從“堅持相同的代碼”中分開,從而產生Strategy策略模式。 示例代碼:
#include <iostream>
using namespace std;
class NameStrategy{
public:
virtual void greet() = 0;
};
class SayHi:public NameStrategy{
public:
void greet(){cout <<"Hi!How's it going?"<<end;}
};
class Ignore:public NameStrategy{
public:
void greet(){cout << "(Pretent I don't see you)" <<endl;}
};
class Admission:public NameStrategy{
public:
void greet(){cout<<"I'm sorry.I forgot your name."<<endl;}
};
//The "Context" controls the strategy:
class Context{
NameStrategy& strateagy;
pubic:
Context(NameStrategy& strat):strategy(strat){}
void greet()
{strategy.greet();}
};
int main()
{
SayHi sayhi;
Ignore ignore;
Admission admission;
Context c1(sayhi),c2(ignore),c3(admission);
c1.greet();
c2.greet();
c3.greet();
}
在main()中就可以看到,運行時的策略選擇。
Chain of Responsibility職責鏈模式可看作是一個策略對象的遞歸調用,本質是嘗試多個解決方法,直到找到一個起作用的。實際上它是個鏈表,可動態創建。這里我們可以用STL來實現。
示例代碼:
#include <iostream>
#include <vector>
using namespace std;
enum Answer(NO.YES);
class GimmeStrategy{
public:
virtual Answer canIHave()=0;
virtual ~GimmeStrategy();
};
class AsdRom:public GimmeStrategy{
public:
Answer canIHave(){
cout << "Moom?Can I have this?"<<endl;
return NO;}
};
class AsdDad:public GimmeStrategy{
public:
Answer canIHave(){
cout << "Dad,I really need this!" <<endl;
return NO;}
};
class AsdGrandpa:public GimmeStrategy{
public:
Answet canIHave(){
cout<<"Grandpa.is it my birthday yet?"<<endl;
return YES;}
};
class Gimme:public GimmeStrategy{
vector<GimmeStrategy*> chain;
public:
Gimme(){
chain.push_back(new AskMom());
chain.push_back(new AskDad());
chain.push_back(new AskGrandpa());
chain.push_back(new AskGrandma());
}
Answer canIHave(){
vector<GimmeStrategy*>::iterator it = chain.begin();
while(it != chain.end())
if(*it++)->canIHave()==YES)
return YES;
cout << "Whiiiiinne!"<<endl;
retunr NO;
}
~Gimme(){purge(chain);}
};
int main()
{
Gimme chain;
chain.canIHave();
}
在GOF的原著中,側重于鏈表的創建,由于STL的存在,創建鏈表變得很輕松。