责任链模式

定义

责任链模式(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. Mac Snipaste 不仅仅是截图工具,不在菜单栏显示,怎么样修改快捷键

    官网下载: https://www.snipaste.com Snipaste 免费,支持 Windows.Mac,Windows 上的功能相当多而且,Mac 也够用了 不仅仅是个截图工具,具有强大功 ...

  2. 41. 干货系列从零用Rust编写负载均衡及代理,websocket与tcp的映射,WS与TCP互转

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...

  3. nginx: [emerg] unknown directive "?server" in /etc/nginx/conf.d/nginx.conf:1

    问题描述:启动nginx的时候报错 1.nginx: [warn] the "user" directive makes sense only if the master proc ...

  4. OS | 透过 inode 来理解硬链接和软链接

    什么是inode? 每个文件都对应一个唯一的inode,inode用来存储文件的元信息,包括: 对应的文件 文件字节数 文件数据块的位置 文件的inode号码 文件的硬链接数 文件的读写权限 文件的时 ...

  5. AtCoder ABC 206

    比赛链接:Here AB水题,跳过 C - Swappable 在数组中找到满足条件的数对 \((i,j)\) \(1 \le i < j \le N (N\in[2,3e5])\) \(A_i ...

  6. 文件上传accept参数可接受的类型汇总

    https://www.cnblogs.com/huihuihero/p/17012817.html 1 // 文件上传accept接受的文件类型 2 3 export const fileTypes ...

  7. P5719 水题

    https://www.luogu.com.cn/problem/P5719 唠唠:别看这题很水,且只要求保留小数点后一位,倘若用float而不是double的话就无法AC,洛谷评测则只有40分.所以 ...

  8. C#设计模式15——观察者模式的写法

    是什么: 观察者模式是一种设计模式,它定义了对象之间的一种一对多的依赖关系,使得当一个对象状态发生改变时,它的所有依赖者都能够得到相应的通知并作出相应的反应.观察者模式也被称为发布-订阅模式. 为什么 ...

  9. Angular系列教程之zone.js和NgZone

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  10. 同步FIFO设计

    FIFO有一个读口和一个写口,读写时钟一致是同步FIFO,时钟不一致就是异步FIFO IP设计中通常使用的是同步FIFO 异步FIFO通常使用在跨时钟域设计中 RAM(Random Access Me ...