设计模式 - 策略和职责链模式 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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值