设计模式(15)职责链模式

职责链模式简介

在公司提交某个流程之后,一般需要多级领导审批。实际代码开发中,也会遇到这种制度,不同的代码模块只能有特定的权限,职责链模式解决了这种问题。

职责链模式又叫责任链模式。很多情况下,可以处理某个请求的对象可能不止一个,请求可以沿着某一条对象之间形成的关系一级一级由下家传递到上家,形成一条链——职责链。职责链可以是直线,也可以是环或树形结构。常见的职责链形式是直线。链上的每一个对象都是请求的处理者,客户端要做的仅仅是发送请求,不需要关心请求的处理细节过程。由此,职责链模式将请求者和请求的接收者解耦。

职责链模式:避免将一个请求的发送者和接收者耦合在一起,让多个对象都有机会处理请求。将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止。

职责链模式结构

在这里插入图片描述
从图中可以看出,职责链模式一共有两个角色:

  • Handler(抽象处理者):抽象处理者一般为抽象类,声明了一个处理请求的接口handleRequest(),定义了一个抽象处理者类型的对象,作为其对下家的引用,通过该引用可以形成一条责任链。
  • ConcreteHandler(具体处理者): 是抽象处理者的子类,实现了处理请求的接口。在具体的实现中,如果该具体处理者能够处理该请求,就处理它,否则将该请求转发给后继者。具体处理者可以访问下一个对象。

由上述可知,在职责链模式中很多对象由每一个对象对其下家的引用连接起来形成一条链条,请求在这个链条上逐级传递,知道某一级能够处理这个请求为止。客户端不知道也不必知道是哪一级处理者处理了该请求,因为每个处理者都有相同的接口handleRequest()。

职责链模式代码实例

接下来通过一个实例来进一步认识职责链模式。
ChainOfResponsibility.h

#include <mutex>
#include <time.h>

using namespace std;

// 请求:票据
class Bill
{
    
    
public:
  Bill() {
    
    }

  Bill(int iId, string iName, double iAccount)
  {
    
    
    id = iId;
    name = iName;
    account = iAccount;
  }

  double getAccount()
  {
    
    
    return this->account;
  }

  void print()
  {
    
    
    cout << "\nID:\t\t" << id << endl;
    cout << "Name:\t\t" << name.c_str() << endl;
    cout << "Account:\t" << account << endl;
  }

private:
  int id;
  string name;
  double account;
};

// 抽象处理者
class Approver
{
    
    
public:
  Approver() {
    
    }

  Approver(string iName)
  {
    
    
    setName(iName);
  }
  
  // 添加上级
  void setSuperior(Approver *iSuperior)
  {
    
    
    this->superior = iSuperior;
  }
  
  // 处理请求
  virtual void handleRequest(Bill *) = 0;
  
  string getName()
  {
    
    
    return name;
  }
  
  void setName(string iName)
  {
    
    
    name = iName;
  }

protected:
  Approver *superior;

private:
  string name;
};

// 具体处理者:组长
class GroupLeader : public Approver
{
    
    
public:
  GroupLeader() {
    
    }

  GroupLeader(string iName)
  {
    
    
    setName(iName);
  }
  
  // 处理请求
  void handleRequest(Bill *bill)
  {
    
    
    if (bill->getAccount() < 10)
    {
    
    
      cout << "组长" << this->getName().c_str() << "处理了该票据,票据信息:";
      bill->print();
    }
    else
    {
    
    
      cout << "组长无权处理,转交上级……" << endl;
      this->superior->handleRequest(bill);
    }
  }
};

// 具体处理者:主管
class Head : public Approver
{
    
    
public:
  Head() {
    
    }

  Head(string iName)
  {
    
    
    setName(iName);
  }
  
  // 处理请求
  void handleRequest(Bill *bill)
  {
    
    
    if (bill->getAccount() >= 10 && bill->getAccount() < 30)
    {
    
    
      cout << "主管" << this->getName().c_str() << "处理了该票据,票据信息:";
      bill->print();
    }
    else
    {
    
    
      cout << "主管无权处理,转交上级……" << endl;
      this->superior->handleRequest(bill);
    }
  }
};

// 具体处理者:经理
class Manager : public Approver
{
    
    
public:
  Manager() {
    
    }

  Manager(string iName)
  {
    
    
    setName(iName);
  }
  
  // 处理请求
  void handleRequest(Bill *bill)
  {
    
    
    if (bill->getAccount() >= 30 && bill->getAccount() < 60)
    {
    
    
      cout << "经理" << this->getName().c_str() << "处理了该票据,票据信息:";
      bill->print();
    }
    else
    {
    
    
      cout << "经理无权处理,转交上级……" << endl;
      this->superior->handleRequest(bill);
    }
  }
};

// 具体处理者:老板
class Boss : public Approver
{
    
    
public:
  Boss() {
    
    }

  Boss(string iName)
  {
    
    
    setName(iName);
  }
  
  // 处理请求
  void handleRequest(Bill *bill)
  {
    
    
    cout << "老板" << this->getName().c_str() << "处理了该票据,票据信息:";
    bill->print();
  }
};

ChainOfResponsibility.cpp

#include <iostream>
#include "ChainOfResponsibility.h"

int main()
{
    
    
  Approver *zuzhang, *zhuguan, *jingli, *laoban;

  zuzhang = new GroupLeader("组长");
  zhuguan = new Head("主管");
  jingli = new Manager("经理");
  laoban = new Boss("老板");

  zuzhang->setSuperior(zhuguan);
  zhuguan->setSuperior(jingli);
  jingli->setSuperior(laoban);

  // 创建报销单
  Bill *bill1 = new Bill(1, "Member1", 8);
  Bill *bill2 = new Bill(2, "Member2", 14.4);
  Bill *bill3 = new Bill(3, "Member3", 32.9);
  Bill *bill4 = new Bill(4, "Member4", 89);

  // 全部先交给组长审批
  zuzhang->handleRequest(bill1);
  cout << endl;
  zuzhang->handleRequest(bill2);
  cout << endl;
  zuzhang->handleRequest(bill3);
  cout << endl;
  zuzhang->handleRequest(bill4);
  cout << endl;

  delete zuzhang;
  delete zhuguan;
  delete jingli;
  delete laoban;
  delete bill1;
  delete bill2;
  delete bill3;
  delete bill4;

  return 0;
}

职责链模式总结

优点:

  • 将请求的接收者和处理者解耦,客户端无需知道具体处理者,只针对抽象处理者编程,简化了客户端编程过程,降低系统耦合度;
  • 在系统中增加一个新的处理者时,只需要继承抽象处理者,重新实现handleRequest()接口,无需改动原有代码,符合开闭原则;
  • 给对象分配职责时,职责链模式赋予系统更多灵活性。

缺点:

  • 请求没有一个明确的接收者,有可能遇到请求无法响应的问题;
  • 比较长的职责链,其处理过程会很长;
  • 建立职责链的工作是在客户端进行,如果建立不当,可能导致循环调用或者调用失败。

适用环境:

  • 有多个对象处理同一个请求,具体由谁来处理是在运行时决定,客户端只需发出请求到职责链上,而无需关心具体是谁来处理;
  • 可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变职责链中各个处理者之间的上下级关系。

Guess you like

Origin blog.csdn.net/qq_24649627/article/details/115397757