设计模式之职责链模式

相信大家都玩过类似于“斗地主”的纸牌游戏,某人出牌给他的下家,下家看看手中的牌,如果要不起,则将出牌请求转发给他的下家,其下家再进行判断。一个循环下来,如果其他人都要不起该牌,则最初的出牌者可以打出新

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

  相信大家都玩过类似于“斗地主”的纸牌游戏,某人出牌给他的下家,下家看看手中的牌,如果要不起,则将出牌请求转发给他的下家,其下家再进行判断。一个循环下来,如果其他人都要不起该牌,则最初的出牌者可以打出新牌。在这个过程中,纸牌作为一个请求沿着一条链在传递,每一位纸牌的玩家都可以处理该请求。在设计模式中,也有一种专门用于处理这种请求链式的模式,它就是职责链模式。

一 职责链模式概述

1.1 职责链模式简介

职责链(Chain of Responsibility)模式:避免将请求发送者与接受者耦合在一起,让多个对象都有机会接受请求,将这些对象连成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。  

1.2 需求

需求背景:M公司承接了某企业SCM(Supply Chain Management,供应链管理)系统的开发任务,其中包含一个采购审批子系统。该企业的采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批:主任可以审批5万元以下(不包括5万)的采购单,副董事长可以审批5万~10万(不包括10万)的采购单,50万元以及以上的采购单就需要开董事会讨论决定,如下图所示:

设计模式之职责链模式

1.3 类图

  设计模式之职责链模式

1.4 代码实现

1.4.1 抽象执行者类

// 抽象执行者类
class AbstractApprover
{
public:
    explicit AbstractApprover(string strName = ""){} // 防止隐式转换
    virtual ~AbstractApprover(){}

    void SetSucessor(AbstractApprover* pSucessor)
    {
        m_pSucessor = pSucessor;
    }

    virtual void ProcessRequest(CRequestX *) = 0;

protected:
    string m_strName;
    AbstractApprover* m_pSucessor;
};

1.4.2 主管类

// 主管类
class CDirector : public AbstractApprover
{
public:
    explicit CDirector(string strName = "")
    {
        m_strName = strName;
    }

    ~CDirector(){}

    void ProcessRequest(CRequestX *pRequest)
    {
        if (pRequest->m_fAmount < 50000)
        {
            cout << "主管:"<< m_strName.c_str() << "审批采购单:" << pRequest->m_strNumber.c_str() << " " << 
                pRequest->m_fAmount << " " << "元," << "采购目的" << pRequest->m_strPurpose.c_str() << endl;
        }
        else
        {
            m_pSucessor->ProcessRequest(pRequest);
        }
    }    
};

1.4.3 副总裁类

// 副总裁类
class CVicePresident : public AbstractApprover
{
public:
    explicit CVicePresident(string strName = "")
    {
        m_strName = strName;
    }

    ~CVicePresident(){}

    void ProcessRequest(CRequestX *pRequest)
    {
        if (pRequest->m_fAmount < 100000)
        {
            cout << "副总裁:"<< m_strName.c_str() << "审批采购单:" << pRequest->m_strNumber.c_str() << " " << 
                pRequest->m_fAmount << " " << "元," << "采购目的" << pRequest->m_strPurpose.c_str() << endl;
        }
        else
        {
            m_pSucessor->ProcessRequest(pRequest);
        }
    }    
};

1.4.4 总裁类

// 总裁类
class CPresident : public AbstractApprover
{
public:
    explicit CPresident(string strName = "")
    {
        m_strName = strName;
    }

    ~CPresident(){}

    void ProcessRequest(CRequestX *pRequest)
    {
        if (pRequest->m_fAmount < 500000)
        {
            cout << "总裁:"<< m_strName.c_str() << "审批采购单:" << pRequest->m_strNumber.c_str() << " " << 
                pRequest->m_fAmount << " " << "元," << "采购目的" << pRequest->m_strPurpose.c_str() << endl;
        }
        else
        {
            m_pSucessor->ProcessRequest(pRequest);
        }
    }    
};

1.4.5 董事会类

// 董事会类
class CCongress : public AbstractApprover
{
public:
    explicit CCongress(string strName = "")
    {
        m_strName = strName;
    }

    ~CCongress(){}

    void ProcessRequest(CRequestX *pRequest)
    {
        cout << "董事会:"<< m_strName << "审批采购单:" << pRequest->m_strNumber << " " << 
            pRequest->m_fAmount << " " << "元," << "采购目的" << pRequest->m_strPurpose << endl;
    }    
};

1.5 测试

#include "stdio.h"

#include "responsibility.h"

void main()
{
    // 创建职责链
    AbstractApprover *PDirector = new CDirector("主管");
    AbstractApprover *pVicePresident = new CVicePresident("副总裁");
    AbstractApprover *pPresident = new CPresident("总裁");
    AbstractApprover *pCongress = new CCongress("董事会");

    PDirector->SetSucessor(pVicePresident);
    pVicePresident->SetSucessor(pPresident);
    pPresident->SetSucessor(pCongress);

    // 构造采购请求单并发送审批请求
    CRequestX* request1 = new CRequestX(45000.00,
        "MANULIFE201706001",
        "购买PC和显示器");
    PDirector->ProcessRequest(request1);

    CRequestX* request2 = new CRequestX(60000.00,
        "MANULIFE201706002",
        "2017开发团队活动");
    PDirector->ProcessRequest(request2);

    CRequestX* request3 = new CRequestX(160000.00,
        "MANULIFE201706003",
        "2017公司年度旅游");
    PDirector->ProcessRequest(request3);

    CRequestX* request4 = new CRequestX(800000.00,
        "MANULIFE201706004",
        "租用新临时办公楼");
    PDirector->ProcessRequest(request4);

    return;
}

设计模式之职责链模式

二 职责链模式总结

2.1 主要优点

  (1)使得一个对象无需知道是其他哪一个对象处理其请求,对象仅需知道该请求会被处理即可,且链式结构由客户端创建 => 降低了系统的耦合度

  (2)在系统中增加一个新的具体处理者无须修改原有系统源代码,只需要在客户端重新建立链式结构即可 => 符合开闭原则

2.2 主要缺点

  (1)由于一个请求没有一个明确地接受者 => 无法保证它一定会被处理

  (2)对于较长的职责链 => 系统性能有一定影响且不利于调试

  (3)如果建立链不当,可能会造成循环调用 => 导致系统进入死循环

2.3 应用场景

  (1)有多个对象处理同一个请求且无需关心请求的处理对象时谁以及它是如何处理的 => 比如各种审批流程

  (2)可以动态地指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序 => 比如各种流程定制

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120138.html原文链接:https://javaforall.net

(0)
上一篇 2021年12月28日 上午11:00
下一篇 2021年12月28日 上午11:00


相关推荐

  • 深入理解设计模式之建造者模式

    深入理解设计模式之建造者模式老大突然拉住我,喜滋滋地告诉我:“公司很满意我们做的模型,又签订了一个合同,把奔驰、宝马的车辆模型都交给我们公司制作了,不过这次额外增加了一个新需求:汽车的启动、停止、喇叭声音、引擎声音都由客户自己控制,想什么顺序就什么顺序”那我们开始设计,来看一下类图:类图比较简单,在CarModel中我们定义了一个setSequence方法,车辆模型的这几个动作要如何排布,是在这个ArrayList中定义的。然后run()方法根据sequence定义的顺序完成指定的顺序动作。我们来看模型抽象类代码:

    2025年6月25日
    10
  • 软件架构模式和设计模式的区别_几种常见软件架构

    软件架构模式和设计模式的区别_几种常见软件架构什么是架构?  软件体系结构通常被称为架构,指可以预制和可重构的软件框架结构。架构尚处在发展期,对于其定义,学术界尚未形成一个统一的意见,而不同角度的视点也会造成软件体系结构的不同理解,以下是一些主流的标准观点。ANSI/IEEE610.12-1990软件工程标准词汇对于体系结构定义是:“体系架构是以构件、构件之间的关系、构件与环境之间的关系为内容的某一系统的基本组织结构以及知道上

    2022年10月18日
    4
  • 23种设计模式(2):工厂方法模式

    23种设计模式(2):工厂方法模式

    2021年11月13日
    50
  • 常用设计模式总结

    常用设计模式总结设计模式(Designpattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,是可复用面向对象软件的基础。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中…

    2022年7月16日
    17
  • 五、工厂模式—旅行的钱怎么来 #和设计模式一起旅行#

    君子爱财,取之有道!—— 出自《增广贤文》### 故事背景上一篇我和MM相约好了,去旅行了,但是旅行是需要Money的啊,作为有个搬砖的码农,没钱啊,怎么呢!不能穷游啊,真是愁人啊 !哎 ,办法总归困难多,这一篇就是写写如何通过工厂拿到钱,然后开始我们的旅行,为一路上能胡吃海喝打下基础!下面开始我们的造钱之旅!“` public class Client{publi…

    2022年2月27日
    38
  • 深入理解设计模式-责任链模式(职责链模式)

    深入理解设计模式-责任链模式(职责链模式)文章目录一 定义二 使用场景三 代码样例 1 需求 2 设计一个所有处理器都要实现的接口 3 实现各种处理器 4 客户端 5 输出四 要点与优缺点结尾一 定义避免请求发送者与接收者耦合在一起 让多个对象都有可能接收请求 将这些对象连接成一条链 并且沿着这条链传递请求 直到有对象处理它为止二 使用场景一个请求需要被多个对象中的某一个处理 但是到底是哪个对象必须在运行时根据条件决定 可以看到责任链模式只有两个角色 Handler 所有处理器类的接口 ConcreteHand 具体的处理

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号