责任链模式

定义

责任链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的藕合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到一个对象处理完为止。

是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止。责任链模式把多个处理器串成链,然后让请求在链上传递。

举个栗子

比如学生请假,小于等于 2 天班主任可以审批;小于等于 7 天,系主任可以审批;小于或等于 10 天,院长可以批准。其他情况,不予审批。

用责任链模式设计审批流程,每个审核者只关心自己责任范围内的请求,并且处理它。对于超出自己责任范围的,扔给下一个审核者处理,这样,将来继续添加审核者的时候,不用改动现有逻辑。

优点

1、降低耦合度。它将请求的发送者和接收者解耦;

2、简化了对象。使得对象不需要知道链的结构;

3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任;

4、增加新的请求处理类很方便。

缺点

不能保证请求一定被接收

适用范围

1、多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定;

2、可动态指定一组对象处理请求,或添加新的处理者;

3、需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

代码实现

上面学生请假的栗子:

学生请假,小于等于 2 天班主任可以审批;小于等于 7 天,系主任可以审批;小于或等于 10 天,院长可以批准。其他情况,不予审批。

type Teacher interface {
HaveRight(day int) bool
HandleApproveRequest(name string, day int) bool
} type RequestChain struct {
Teacher
approver *RequestChain
} func (r *RequestChain) SetApprover(m *RequestChain) {
r.approver = m
} func (r *RequestChain) HandleApproveRequest(name string, day int) bool {
if r.Teacher.HaveRight(day) {
return r.Teacher.HandleApproveRequest(name, day)
}
if r.approver != nil {
return r.approver.HandleApproveRequest(name, day)
}
fmt.Println("请假时间太久了,不予审批")
return false
} func (r *RequestChain) HaveRight(day int) bool {
return true
} type HeadTeacher struct{} func NewHeadTeacherChain() *RequestChain {
return &RequestChain{
Teacher: &HeadTeacher{},
}
} func (*HeadTeacher) HaveRight(day int) bool {
return day <= 2
} func (*HeadTeacher) HandleApproveRequest(name string, day int) bool {
fmt.Println(fmt.Sprintf("班主任,批准了%s的请假申请,请假天数%d", name, day))
return true
} type DepTeacher struct{} func NewDepManagerChain() *RequestChain {
return &RequestChain{
Teacher: &DepTeacher{},
}
} func (*DepTeacher) HaveRight(day int) bool {
return day <= 7
} func (*DepTeacher) HandleApproveRequest(name string, day int) bool {
fmt.Println(fmt.Sprintf("系主任,批准了%s的请假申请,请假天数%d", name, day))
return true
} type DeanTeacher struct{} func NewDeanTeacherChain() *RequestChain {
return &RequestChain{
Teacher: &DeanTeacher{},
}
} func (*DeanTeacher) HaveRight(day int) bool {
return day <= 10
} func (*DeanTeacher) HandleApproveRequest(name string, day int) bool {
fmt.Println(fmt.Sprintf("院长,批准了%s的请假申请,请假天数%d", name, day))
return true
}

测试代码

func TestApproveChain(t *testing.T) {
c1 := NewHeadTeacherChain()
c2 := NewDepManagerChain()
c3 := NewDeanTeacherChain() c1.SetApprover(c2)
c2.SetApprover(c3) var c Teacher = c1
assert.Equal(t, true, c.HandleApproveRequest("小明", 3))
assert.Equal(t, true, c.HandleApproveRequest("小红", 2))
assert.Equal(t, false, c.HandleApproveRequest("小龙", 30))
}

输出

系主任,批准了小明的请假申请,请假天数3
班主任,批准了小红的请假申请,请假天数2
请假时间太久了,不予审批

责任链模式对比装饰模式

责任链和装饰模式非常相似。两者都依赖递归组合将需要执行的操作传递给一系列对象。来看下两者的不同点。

1、责任链的管理者可以相互独立地执行一切操作,还可以随时停止传递请求。

2、装饰模式可以对对象进行扩展,但是不能中断请求的传递。

参考

【文中代码】https://github.com/boilingfrog/design-pattern-learning/tree/master/责任链模式

【大话设计模式】https://book.douban.com/subject/2334288/

【极客时间】https://time.geekbang.org/column/intro/100039001

【责任链模式(责任链模式)详解】http://c.biancheng.net/view/1383.html

【责任链模式】https://boilingfrog.github.io/2021/11/22/使用go实现责任链模式/

设计模式学习-使用go实现责任链模式的更多相关文章

  1. 设计模式之二十:责任链模式(Chain of Responsibility)

    感觉这个设计模式和组合模式一样是一种非常巧妙的设计模式,在须要使用它的地方假设不使用这样的设计模式代码会变的非常复杂,可是这样的设计模式的基本原理又是非常easy的. 责任链模式: 通过使多个对象都有 ...

  2. 【设计模式】行为型05责任链模式(Chain of responsibility Pattern)

    学习地址:http://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html demo采用了DEBUG级别举例子,理解起 ...

  3. 设计模式(C#)——12责任链模式

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321 前言        在开发游戏过程中,当玩家合成一种道具的时候,对于不痛的道具,需要的碎片个数,类型是不同的.用传统的写法,就是 ...

  4. python 设计模式之 (Chain of Responsibility)责任链模式

    #写在前面 对于每一种设计模式,如果不理解它的原理和结构,是写不出例子来的.所以弄明白很重要. 等过完这段浑浑噩噩的日子,我要找个遍地开花的地方开怀大笑一场 #责任链模式定义 简书上一网友就把这个定义 ...

  5. C#设计模式学习笔记:(20)职责链模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8109100.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第八个模式--职 ...

  6. iOS设计模式解析(五)责任链模式

    责任链模式:使多个对象都有机会处理请求,从而避免发送者和接受者之间发生耦合. 应用场景: 有多个对象可以处理请求,而处理程序只有在运行时才能确定 例如: 英雄联盟中伤害计算,伤害类型分为AP.AD.真 ...

  7. 设计模式(13)--Chain of Responsibility(责任链模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一 ...

  8. java设计模式8.迭代子模式、责任链模式、命令模式

    迭代子模式 迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象.它将迭代逻辑封装到一个独立的迭代子对象中,从而与聚集本身分开.迭代子对象是对遍历的抽象化,不同的聚集对象可以提供相同的迭代 ...

  9. 《精通Python设计模式》学习行为型之责任链模式

    感觉是全新的学习了. 因为在以前的工作中,并没有有意识的去运用哪一种编程模式. 以后要注意的了. 这才是高手之路呀~ class Event: def __init__(self, name): se ...

  10. Java设计模式13:责任链模式

    前言 来菜鸟这个大家庭10个月了,总得来说比较融入了环境,同时在忙碌的工作中也深感技术积累不够,在优秀的人身边工作必须更加花时间去提升自己的技术能力.技术视野,所以开一个系列文章,标题就轻松一点叫做最 ...

随机推荐

  1. Nacos 服务状态监听四种写发

    监听服务的四种实现方式,以监听 Nacos 服务为例 1. 传统方式 public void subscribe() { try { NamingService namingService = Nam ...

  2. 阿里云 AI 编辑部获 CCBN 创新奖,揭秘传媒行业解决方案背后的黑科技

    5 月 27 日,CCBN(第二十八届中国国际广播电视信息网络展览会)在北京隆重召开,在本次的 "CCBN 年度创新奖" 评选中,阿里云视频云凭借AI 编辑部的传媒行业专业解决方案 ...

  3. Codeforces Round #712 (Div. 2) 个人题解

    这一场打的又很差(掉分预定),D题想不出来. A. Déjà Vu 这题首先判断字符串是否全由 a 组成,如果是的话输出 NO int main() { ios_base::sync_with_std ...

  4. KCD技术分享:以SBOM为基础的云原生应用安全治理

    随着越来越多的企业和组织将他们的应用迁移到云上,云原生技术的应用部署和管理正在变得更加灵活和高效,但也相应地引入了一些新的安全风险.2023年4月15日,由云原生计算基金会(CNCF)发起,全球各国当 ...

  5. arguments使用

    arguments在函数中可以使用,表示包含了当前函数调用时传入的实参. arguments通过索引值获取实参,索引值从开始,按顺序依次表示函数调用时传过来的实参. 1 // arguments的使用 ...

  6. 每天学五分钟 Liunx 0010 | 软件篇: RPM 和 YUM

    1. RPM RPM(RedHat Package Manager),顾名思义是 RedHat 的软件包管理器.它遵循 GPL 规则且功能强大好用,从而逐渐运用到其它 Liunx 发行版中,包括 Fe ...

  7. spring--是如何解决单例模式下循环依赖问题的

    Spring 解决单例 bean 的循环依赖主要依赖于容器的三级缓存机制,以及 bean 的提前暴露.这里是它如何工作的: 三级缓存: 一级缓存(singletonObjects):存储已经经过完整生 ...

  8. Latex常用数学符号输入方法

    引用CSDN博文 https://blog.csdn.net/qq_25368751/article/details/87888974

  9. 【C++】类概念及使用

    类定义中不允许对数据成员初始化 类外只能访问公有部分 类成员必须指定访问属性 类的成员函数是实现对封装的数据成员进行操作的唯一途径 类定义中不允许定义本类对象,因无法预知大小 类与结构形式相同,唯一区 ...

  10. 07 - HTTP

    HTTP 强烈推荐学习:HTTP | MDN 一 .基础概念 请求和响应报文 客户端发送一个请求报文给服务器,服务器根据请求报文中的信息进行处理,并将处理结果放入响应报文中返回给客户端. 请求报文结构 ...