责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。

使用背景

  1. 请求的处理涉及多个步骤或者可能有多个处理器处理请求: 当请求需要经过一系列处理步骤,并且这些步骤可能由不同的处理器来处理时,责任链模式可以很好地应用。例如,在订单处理系统中,订单可能需要经过验证、审批、库存检查等多个步骤,每个步骤由不同的处理器来处理。

  2. 需要动态指定处理器链: 责任链模式允许在运行时动态地组织处理器链,而不需要在编码时固定链的顺序。这样可以更灵活地根据需求组织不同的处理逻辑。例如,根据用户的权限动态地调整请求处理链。

  3. 解耦请求的发送者和接收者: 责任链模式可以将请求发送者和请求接收者解耦,发送者不需要知道具体是哪个处理器来处理请求,只需要将请求发送给责任链的第一个节点,然后由责任链自行决定如何处理。这样可以降低系统的耦合度,提高代码的灵活性和可维护性。

  4. 支持动态添加或删除处理器: 责任链模式支持在运行时动态地添加或删除处理器,这样可以灵活地调整系统的处理逻辑,而不需要修改已有的代码。例如,当系统需求变更或者需要对处理流程进行优化时,可以通过添加或删除处理器来实现。

  5. 避免请求的发送者与接收者之间的直接耦合: 通过责任链模式,请求的发送者无需知道具体的处理者是谁,也无需知道处理者的具体顺序,只需将请求发送给责任链的第一个处理者,由责任链自行决定如何处理请求。这种松耦合的设计可以提高系统的灵活性和可扩展性。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main

import "fmt"

type Handler interface {
SetNextHandler(next Handler)
HandleRequest(member Member)
}

// 具体处理者 - 用户名校验器
type UsernameValidator struct {
nextHandler Handler
}

func (u *UsernameValidator) SetNextHandler(next Handler) {
u.nextHandler = next
}

func (u *UsernameValidator) HandleRequest(member Member) {
if member.LoginName == "" {
fmt.Println("用户名不能为空")
} else if u.nextHandler != nil {
u.nextHandler.HandleRequest(member)
}
}

// 具体处理者 - 密码校验器
type PasswordValidator struct {
nextHandler Handler
}

func (p *PasswordValidator) SetNextHandler(next Handler) {
p.nextHandler = next
}

func (p *PasswordValidator) HandleRequest(member Member) {
if member.LoginPass == "" {
fmt.Println("密码不能为空")
} else if p.nextHandler != nil {
p.nextHandler.HandleRequest(member)
}
}

// 具体处理者 - 角色校验器
type RoleValidator struct{}

func (r *RoleValidator) SetNextHandler(next Handler) {
// 角色校验器不需要下一个处理者
}

func (r *RoleValidator) HandleRequest(member Member) {
if member.RoleName != "管理员" {
fmt.Println("您不是管理员,无操作权限")
} else {
fmt.Println("您是管理员,允许操作")
}
}

// 会员结构体
type Member struct {
LoginName string
LoginPass string
RoleName string
}

func main() {
member := Member{
LoginName: "maxwell",
LoginPass: "password123",
RoleName: "管理员",
}

usernameValidator := &UsernameValidator{}
passwordValidator := &PasswordValidator{}
roleValidator := &RoleValidator{}

usernameValidator.SetNextHandler(passwordValidator)
passwordValidator.SetNextHandler(roleValidator)

usernameValidator.HandleRequest(member)
}


结语

责任链模式是一种优雅且可扩展的设计模式,常用于处理请求的场景,例如请求过滤、日志记录、权限验证等。通过合理地组织处理者链,我们可以轻松地添加、移除或修改处理者,而不会影响其他部分的代码。


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。