设计模式简单代码之Chain Of Responsibility 模式(小孩要苹果篇)

/**********************************************************************************************************/

* 作者:一雨田(http://blog.csdn.net/dylgsy/)。本文可随便转贴,但请保留此信息

* Chain Of Responsibility(职责链模式)适用于:
*
* 1、有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
*
* 2、你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
*
* 3、可处理一个请求的对象集合应被动态指定。
/**********************************************************************************************************/

/**********************************************************************************************************/
* 如果客户的请求(Request)可以由好多个对象去处理,而这些对象可能组成一条链的关系,我们就可以使用职责链模式。
*
* 这些处理Request的类之间是一个松散的耦合,唯一共同点是在他们之间可以传递request。
*
* 考虑一个实例:
*
* 一个小孩子想吃苹果,那他会向家里面的成员请求,家里的成员包括妈妈、爸爸、奶奶、爷爷,这些请求就会沿着
*
* 这条链传送下去。
*
* 串起职责链有很多方法,这里用的是GOF书本里的方法,当然我们也可以使用链表等的方法来串起来。
*
* 下面我们来看看如何用代码来组织这个模式
/**********************************************************************************************************/

#include <stdio.h>
#include <iostream>
using namespace std;

// 这个模式需要定义一个公共接口,属于这条链里的对象全部都派生于它
class Handler
{
public:
 
 // 这个构造函数实际就是指定后继者
 Handler(Handler *s) : _successor(s) { }
 virtual ~Handler()
 {
 }

 // 处理请求的函数
 virtual void HandleRequest()
 {
  if(_successor)
  {
   cout << "孩子,我没有苹果,去问" << _successor->szName << "拿吧!" << endl;
   _successor->HandleRequest();
  }
  else
  {
   // 没有后继者了,必须想个办法来解决
   cout << "孩子,家里没有苹果了,只能出去买了。" << endl;
  }
 }

 // 是否有苹果
 virtual bool HasHandle()
 {
  return false;
 }
 virtual void SetHandler(Handler *s)
 {
  _successor = s;
 }

public:
 Handler *_successor;
 char szName[20];
};

// 好,接口已经有了,我们现在就可以去派生职责链里的每一个类
// 妈妈类
class Mom: public Handler
{
public:
 Mom(Handler *s) : Handler(s)
 {
  strcpy(szName, "妈妈");
 }
 virtual void HandleRequest()
 {
  if( HasHandle() )
  {
   // 给小孩苹果
   cout << "来,妈妈给你苹果" << endl;
  }
  else
  {
   // 把公共操作转到基类去,这是一个技巧
   // 当然你也可以使用_successor->HandleRequest();
   // 但是这样做如果你想在处理的前后加点额外的行为就很不方便了,要到每个派生类里去加
   Handler::HandleRequest();
  }
 }
 virtual bool HasHandle()
 {
  return false;
 }
};

// 相同的定义爸爸类
class Father: public Handler
{
public:
 Father(Handler *s) : Handler(s)
 {
  strcpy(szName, "爸爸");
 }
 virtual void HandleRequest()
 {
  if( HasHandle() )
  {
   // 给小孩苹果
   cout << "来,爸爸给你苹果" << endl;
  }
  else
  {
   Handler::HandleRequest();
  }
 }
 virtual bool HasHandle()
 {
  return false;
 }
};

// 奶奶类
class GrandMother: public Handler
{
public:
 GrandMother(Handler *s) : Handler(s)
 {
  strcpy(szName, "奶奶");
 }
 virtual void HandleRequest()
 {
  if( HasHandle() )
  {
   // 给小孩苹果
   cout << "来,奶奶给你苹果" << endl;
  }
  else
  {
   Handler::HandleRequest();
  }
 }
 virtual bool HasHandle()
 {
  return false;
 }
};

// 爷爷类
class GrandFather: public Handler
{
public:
 GrandFather(Handler *s) : Handler(s)
 {
  strcpy(szName, "爷爷");
 }
 virtual void HandleRequest()
 {
  if( HasHandle() )
  {
   // 给小孩苹果
   cout << "来,爷爷给你苹果" << endl;
  }
  else
  {
   Handler::HandleRequest();
  }
 }
 virtual bool HasHandle()
 {
  // 如果 return false 则程序需要处理没有后继者的情况
  // 这里是显示家里人都没苹果了,要出去买了
  return true; 
 }
};

// 要苹果
void WantApple(Handler *h)
{
 cout << "问" << h->szName << "拿苹果" << endl;
 h->HandleRequest();
}

void main()
{
 // 串起一条职责链
 GrandFather gf(NULL);
 Father f(&gf);
 GrandMother gm(&f);
 Mom m(&gm);

 WantApple(&m);
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值