【Go-设计模式】职责链模式 详解
概念:
职责链模式 用于 分离不同职责,并且 动态组合相关职责
职责链模式(Chain of Responsibility Pattern), 又叫 责任链模式,为 请求 创建了 一个接收者对象的链
这种模式对 请求的发送者 和 接收者 进行解耦
通常 每个接收者 都包含 对另一个接收者的引用
如果 一个对象不能处理该请求,那么它会把 相同的请求 传给 下一个接收者,依此类推
这种类型的设计模式属于 行为型模式
UML:
- Handler:
抽象的处理器, 定义了一个 处理请求的接口, 同时含有 另外 Handler - ConcreteHandler:
具体的处理器,处理它 自己负责的请求, 可以 访问它的后继者(即:下一个处理者), 如果可以处理当前请求,则处理;
否则,就将该请求交个 后继者 去处理,从而形成一个 职责链 - Request:
表示一个请求,包含很多属性
示例:
请求信息类:
type Request struct {
Attri1 int64
Attri2 string
}
func NewRequest(attri1 int64, attri2 string) Request {
return Request{
Attri1: attri1,
Attri2: attri2,
}
}
抽象的 处理器接口:
type Handler interface {
GetSuccessor() Handler
ProcessRequest(req *Request)
}
具体的处理器类:
具体的处理器1:
type ConcreteHandler1 struct {
Successor Handler
}
func (this ConcreteHandler1) GetSuccessor() Handler {
return this.Successor
}
func (this ConcreteHandler1) ProcessRequest(req *Request) {
fmt.Println("handler1处理了request,处理的request为:", req)
req.Attri1 += 233
}
func NewConcreteHandler1() *ConcreteHandler1 {
return &ConcreteHandler1{}
}
具体的处理器2:
type ConcreteHandler2 struct {
Successor Handler
}
func (this ConcreteHandler2) GetSuccessor() Handler {
return this.Successor
}
func (this ConcreteHandler2) ProcessRequest(req *Request) {
fmt.Println("handler2处理了request,处理的request为:", req)
req.Attri2 = fmt.Sprintf("%s-经过了处理器2的处理", req.Attri2)
this.GetSuccessor().ProcessRequest(req)
}
func NewConcreteHandler2(successor Handler) *ConcreteHandler2 {
return &ConcreteHandler2{
Successor: successor,
}
}
测试:
package main
import (
"DemoProject/design/base23/chain" // 根据自己的项目路径定制
"fmt"
)
func main() {
// chain
handler1 := chain.NewConcreteHandler1()
handler2 := chain.NewConcreteHandler2(handler1)
request := chain.NewRequest(0, "目标请求内容")
handler2.ProcessRequest(&request)
fmt.Println(request)
}
注意事项:
优点:
将 请求 和 处理 分开,实现解耦,提高 系统的灵活性
简化了对象,使对象不需要知道 链的具体结构
缺点:
性能 会受到影响,特别是在链比较长的时候,因此需控制 链中最大节点数量,一般通过在 Handler 中设置一个 最大节点数量,在 setNext()方法中判断是否已经 超过阀值,超过 则 不允许该链建立,避免出现 超长链 无意识地 破坏系统性能
调试不方便。
采用了类似 递归 的方式,调试时逻辑可能比较复杂
应用场景:
有 多个对象 可以 处理同一个请求 时
比如:
- 多级请求
- 请假/加薪等审批流程
- 拦截器
在很多 中间件、框架 设计中,就使用了 责任链模式