首页 > 其他分享 >【设计模式】之责任链模式

【设计模式】之责任链模式

时间:2022-09-26 11:48:01浏览次数:63  
标签:请求 处理 days 模式 责任 对象 int nextHandler 设计模式

定义

责任链模式(Chain of Responsibility Pattern)中,有一条由请求处理者对象组成的链条,每个对象(除最后一个对象外)都持有下一个对象的引用,请求发送者将请求发送给第一个对象,请求就会顺着链条走下去,直到有对象能够处理请求。该模式将多个处理者对象解耦,使得请求发送者只管将请求发送给责任链的第一个对象就是了,不用去关心请求具体是如何被处理的。

组成

抽象请求处理者(Abstract Request Handler):定义处理请求的接口。

具体请求处理者(Concrete Request Handler):持有下一个处理者对象的引用,具体实现处理请求的接口,包括将请求处理掉和传给下一个对象。

客户端(Client):将请求发送给责任链的头部对象。

举例

某学校的学生请假审批流程:

天数 <= 3:班主任审批通过;

3 < 天数 <= 7:班主任审批不通过,交给年级组长,年级组长审批通过;

7 < 天数 <= 30:年级组长审批不通过,交给教务处,教务处审批通过;

30 < 天数 <= 60:教务处审批不通过,交给校长,校长审批通过;

天数 > 60:校长审批不通过。

不用责任链模式写出的代码:

void handleRequest(int days)
{
    if (days <= 3)
    {
        cout << "班主任审批通过。" << endl;
    }
    else
    {
        cout << "班主任审批不通过。交给年级组长。" << endl;
        if (days <= 7)
        {
            cout << "年级组长审批通过。" << endl;
        }
        else
        {
            cout << "年级组长审批不通过。交给教务处。" << endl;
            if (days <= 30)
            {
                cout << "教务处审批通过。" << endl;
            }
            else
            {
                cout << "教务处审批不通过。交给校长。" << endl;
                if (days <= 60)
                {
                    cout << "校长审批通过。" << endl;
                }
                else
                {
                    cout << "校长审批不通过。" << endl;
                }
            }
        }
    }
}

可以看到,这段代码又是一堆if-else又是层层嵌套的,又臭又长,好难看!更重要的问题是,如果流程需要修改,那业务代码也需要修改,不符合开闭原则,难以维护和扩展。

那怎么样提高程序的可扩展性呢?

我们应该把班主任、年级组长等等拆分出来当做请求处理者,并指定一个共同的抽象父类,父类里面定义抽象接口,子类具体实现这些接口。

UML类图:

img

代码:

/** 抽象处理者 */
class AbstractRequestHandler
{
protected:
    AbstractRequestHandler *const nextHandler; // 由于链条中最后一个处理者没有下一个处理者,但是c++不像java那样存在空引用,所以只能用指针了

    const int maxDaysLimit;

    const char *name;

    virtual void handleRequest(int days)
    {
        if (days <= maxDaysLimit)
        {
            cout << name << "审批通过" << endl;
        }
        else
        {
            cout << name << "审批不通过" << endl;
            if (nextHandler)
            {
                cout << "转交给" << nextHandler->name;
                nextHandler->handleRequest(days);
            }
        }
    }

    virtual ~AbstractRequestHandler()
    {
        if (nextHandler)
        {
            delete nextHandler;
        }
    }
}

/** 具体处理者————校长 */
class Principal : public AbstractRequestHandler
{
public:
    Principal() :
        nextHandler(nullptr),
        maxDaysLimit(60),
        name("校长")
    { }
}

/** 具体处理者————教务处 */
class AcademicAffairsOffice : public AbstractRequestHandler
{
public:
    AcademicAffairsOffice() :
        nextHandler(new Principal),
        maxDaysLimit(30),
        name("教务处")
    { }
}

// 年级组长、班主任 略

/** 客户端 */
class Client
{
    HeadTeacher &headTeacher;

    void sendRequest(int days)
    {
        headTeacher.handleRequest();
    }
}

int main()
{
    Client client;
    client.sendRequest();
    return 0;
}

标签:请求,处理,days,模式,责任,对象,int,nextHandler,设计模式
From: https://www.cnblogs.com/YWT-Real/p/16730326.html

相关文章

  • 原型模式(创建型)
    原型模式介绍定义:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。简单理解,就是当需要创建一个指定的对象时,我们刚好有一个这样的对......
  • 抽象工厂模式 Abstract Factory
    “对象创建”模式通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。典型模式......
  • iOS13 禁用深色模式
    iOS13之后,新增了一个深色模式,但有时候我们并喜欢这个模式所以需要禁用深色模式全局禁用在info.plist文件中,添加一对key-string<key>UIUserInterfaceStyle</key><......
  • 初识设计模式 - 代理模式
    简介概念举个简单的例说明代理模式就是:假如现在需要买一辆二手车,可以自己去找车源、做质量检测等一系列车辆过户的流程,但是这实在太浪费时间和精力了,其实可以通过找中介......
  • reactor的三种模式
    Reactor响应式编程,是NIO的编程设计模式 单reactor单线程模式:简单NIO例子中,选择器循环和业务处理线程都用一个线程。也是最简单的NIO编程模式。   单Reacto......
  • 设计模式---享元模式
    简述类型:结构型目的:降低对象创建时大量属性也随之被新建而带来的性能上的消耗话不多说,我们看一个案例。优化案例最初版v0现在需要采购一批办公用的电脑,以下是Compu......
  • 密码学奇妙之旅、01 CFB密文反馈模式、AES标准、Golang代码
    CFB密文反馈模式CFB密文反馈模式属于分组密码模式中的一种。加密与解密使用同一结构,加密步骤生成用于异或的密钥流。其弥补了ECB电子密码本模式的不足(明文中的重复排列会......
  • Ele_0006:electron 在非全屏模式下,显示时 忽略任务栏高度 打开软件时 闪烁图标
    1,    //打开软件时闪烁图标//c.once('focus',()=>c.flashFrame(true));//c.flashFrame(true); ......
  • 三层架构以及MVC设计模式
    三层架构三层架构为什么是三层?过去的软件开发种,没有三层构架,只有数据后台和前端显示,这就导致项目很难维护,还有当业务逻辑复杂时,代码量就会多得多。互联网开发的迭代优化......
  • 工厂方法模式 Factory Method
    “对象创建”模式通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。典型模式......