目录
[责任链模式(Chain of Responsibility Pattern)](#责任链模式(Chain of Responsibility Pattern))
责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链将请求的发送者和接收者解耦,并允许多个对象都有机会处理请求。通过为多个对象构成一个链,并将请求沿着这条链传递,直到有一个对象处理请求为止。在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,请求会自动进行传递。所以责任链将请求的发送者和请求的处理者解耦了。
责任链模式的核心角色:
- 抽象处理者(Handler):定义了处理请求的接口,通常包含一个指向下一个处理者的引用。
- 具体处理者(Concrete Handler):实现了抽象处理者接口,负责处理请求,如果自己不能处理,则将请求传递给下一个处理者
优缺点
(1)优点:
- 降低耦合度。它将请求的发送者和接收者解耦。
- 简化了对象。使得对象不需要知道链的结构。
- 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
- 增加新的请求处理类很方便。
(2)缺点:
- 不能保证请求一定被接收。
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
- 可能不容易观察运行时的特征,有碍于除错。
使用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可动态指定一组对象处理请求。
代码实现
Go
package main
// 请假审批系统,员工可以提交请假申请,申请会依次经过部门经理、人事部门和总经理的审批。
// 如果其中任何一个审批者同意了请假申请,审批流程就结束,否则继续传递给下一个审批者。
import "fmt"
// 抽象处理者:审批者接口
type Approver interface {
SetNext(approver Approver)
ProcessRequest(request Request)
}
// 具体处理者:部门经理
type DepartmentManager struct {
next Approver
}
func (dm *DepartmentManager) SetNext(approver Approver) {
dm.next = approver
}
func (dm *DepartmentManager) ProcessRequest(request Request) {
if request.Type == "Leave" && request.Amount <= 3 {
fmt.Println("Department Manager approved the request.")
} else if dm.next != nil {
dm.next.ProcessRequest(request)
}
}
// 具体处理者:人事部门
type HRDepartment struct {
next Approver
}
func (hr *HRDepartment) SetNext(approver Approver) {
hr.next = approver
}
func (hr *HRDepartment) ProcessRequest(request Request) {
if request.Type == "Leave" && request.Amount <= 7 {
fmt.Println("HR Department approved the request.")
} else if hr.next != nil {
hr.next.ProcessRequest(request)
}
}
// 具体处理者:总经理
type GeneralManager struct {
next Approver
}
func (gm *GeneralManager) SetNext(approver Approver) {
gm.next = approver
}
func (gm *GeneralManager) ProcessRequest(request Request) {
if request.Type == "Leave" && request.Amount <= 10 {
fmt.Println("General Manager approved the request.")
} else {
fmt.Println("Request denied.")
}
}
// 请求结构体
type Request struct {
Type string
Amount int
}
// 客户端代码
func main() {
departmentManager := &DepartmentManager{}
hrDepartment := &HRDepartment{}
generalManager := &GeneralManager{}
departmentManager.SetNext(hrDepartment)
hrDepartment.SetNext(generalManager)
request := Request{
Type: "Leave",
Amount: 5,
}
departmentManager.ProcessRequest(request)
}