责任链模式是一种行为设计模式,它允许多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
减少请求的发送者和接收者之间的耦合。
可以动态地增加或修改处理请求的算法。
可以将请求传递给多个对象中的一个,而不需要明确指定接收者。
有多个对象可以处理一个请求,但具体由哪个对象处理在运行时才能确定。
你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可处理一个请求的对象集合应被动态指定。
下面是一个简单的责任链模式的例子,模拟一个请假审批流程,不同级别的领导可以审批不同天数的请假请求。
package main
import (
"fmt"
)
// 1. 定义处理请求的接口
type Approver interface {
SetNext(approver Approver)
Approve(request *LeaveRequest)
}
// 2. 定义请假请求结构体
type LeaveRequest struct {
Name string
Days int
Approved bool
}
// 3.1 定义具体的处理者:经理
type Manager struct {
next Approver
}
func (m *Manager) SetNext(approver Approver) {
m.next = approver
}
func (m *Manager) Approve(request *LeaveRequest) {
if request.Days <= 3 {
fmt.Printf("Manager approved %s's leave for %d days.\n", request.Name, request.Days)
request.Approved = true
} else if m.next != nil {
m.next.Approve(request)
} else {
fmt.Printf("Manager cannot approve %s's leave for %d days.\n", request.Name, request.Days)
}
}
// 3.2 定义具体的处理者:总监
type Director struct {
next Approver
}
func (d *Director) SetNext(approver Approver) {
d.next = approver
}
func (d *Director) Approve(request *LeaveRequest) {
if request.Days <= 7 {
fmt.Printf("Director approved %s's leave for %d days.\n", request.Name, request.Days)
request.Approved = true
} else if d.next != nil {
d.next.Approve(request)
} else {
fmt.Printf("Director cannot approve %s's leave for %d days.\n", request.Name, request.Days)
}
}
// 3.3 定义具体的处理者:CEO
type CEO struct{}
func (c *CEO) SetNext(approver Approver) {
// CEO 是最高级别的审批者,没有下一个审批者
}
func (c *CEO) Approve(request *LeaveRequest) {
if request.Days <= 30 {
fmt.Printf("CEO approved %s's leave for %d days.\n", request.Name, request.Days)
request.Approved = true
} else {
fmt.Printf("CEO cannot approve %s's leave for %d days.\n", request.Name, request.Days)
}
}
func main() {
// 创建审批者链
manager := &Manager{}
director := &Director{}
ceo := &CEO{}
manager.SetNext(director)
director.SetNext(ceo)
// 创建请假请求
request1 := &LeaveRequest{Name: "Alice", Days: 2}
request2 := &LeaveRequest{Name: "Bob", Days: 5}
request3 := &LeaveRequest{Name: "Charlie", Days: 10}
request4 := &LeaveRequest{Name: "David", Days: 25}
request5 := &LeaveRequest{Name: "Eve", Days: 35}
// 提交请假请求
manager.Approve(request1)
manager.Approve(request2)
manager.Approve(request3)
manager.Approve(request4)
manager.Approve(request5)
}