职责链模式原理

职责链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象依次处理同一个请求,直到其中一个对象能够处理为止。
职责链模式的核心思想是将多个处理对象组成一条链,每个处理对象都有一个对下一个处理对象的引用。当请求进入链中,从链的起点开始,依次传递给每个处理对象,直到有一个对象能够处理该请求为止。
职责链模式包含以下几个角色:
1. 抽象处理者(Handler):抽象处理者定义了一个处理请求的方法,并持有对下一个处理者的引用。
2. 具体处理者(Concrete Handler):具体处理者实现了抽象处理者定义的方法,并根据自身的业务逻辑来判断是否能够处理请求。如果能够处理,则处理请求;如果不能处理,则将请求传递给下一个处理者。
职责链模式的优点包括:
1. 将请求的发送者和接收者解耦,使得请求的发送者不需要知道哪个对象能够处理请求。
2. 可以动态地改变处理链,增加或者删除处理者,灵活性较高。
3. 可以避免请求的发送者和接收者之间的紧耦合关系,提高代码的可扩展性和可维护性。
职责链模式适用于以下场景:
1. 有多个对象可以处理同一个请求,但具体哪个对象能够处理请求在运行时才能确定。
2. 需要动态改变处理链的顺序或者增加新的处理者。
3. 需要将请求的发送者和接收者解耦,避免紧耦合关系。
总结起来,职责链模式通过将多个处理对象组成一条链,依次处理请求,直到有一个对象能够处理为止。这样可以将请求的发送者和接收者解耦,提高代码的灵活性和可维护性。

go案例代码

 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
84
85
86
87
package main

import "fmt"

// 请求结构体
type Request struct {
	Content string
}

// 抽象处理者接口
type Handler interface {
	SetNext(handler Handler)
	HandleRequest(request Request)
}

// 具体处理者A
type ConcreteHandlerA struct {
	nextHandler Handler
}

func (h *ConcreteHandlerA) SetNext(handler Handler) {
	h.nextHandler = handler
}
func (h *ConcreteHandlerA) HandleRequest(request Request) {
	if request.Content == "A" {
		fmt.Println("ConcreteHandlerA 处理了请求")
	} else if h.nextHandler != nil {
		h.nextHandler.HandleRequest(request)
	} else {
		fmt.Println("无处理者能够处理该请求")
	}
}

// 具体处理者B
type ConcreteHandlerB struct {
	nextHandler Handler
}

func (h *ConcreteHandlerB) SetNext(handler Handler) {
	h.nextHandler = handler
}
func (h *ConcreteHandlerB) HandleRequest(request Request) {
	if request.Content == "B" {
		fmt.Println("ConcreteHandlerB 处理了请求")
	} else if h.nextHandler != nil {
		h.nextHandler.HandleRequest(request)
	} else {
		fmt.Println("无处理者能够处理该请求")
	}
}

// 具体处理者C
type ConcreteHandlerC struct {
	nextHandler Handler
}

func (h *ConcreteHandlerC) SetNext(handler Handler) {
	h.nextHandler = handler
}
func (h *ConcreteHandlerC) HandleRequest(request Request) {
	if request.Content == "C" {
		fmt.Println("ConcreteHandlerC 处理了请求")
	} else if h.nextHandler != nil {
		h.nextHandler.HandleRequest(request)
	} else {
		fmt.Println("无处理者能够处理该请求")
	}
}
func main() {
	// 创建具体处理者对象
	handlerA := &ConcreteHandlerA{}
	handlerB := &ConcreteHandlerB{}
	handlerC := &ConcreteHandlerC{}
	// 设置处理链
	handlerA.SetNext(handlerB)
	handlerB.SetNext(handlerC)
	// 创建请求
	requestA := Request{Content: "A"}
	requestB := Request{Content: "B"}
	requestC := Request{Content: "C"}
	requestD := Request{Content: "D"}
	// 处理请求
	handlerA.HandleRequest(requestA)
	handlerA.HandleRequest(requestB)
	handlerA.HandleRequest(requestC)
	handlerA.HandleRequest(requestD)
}

在上面的示例中,我们定义了一个请求结构体(Request),抽象处理者接口(Handler),以及三个具体处理者(ConcreteHandlerA、ConcreteHandlerB、ConcreteHandlerC)。每个具体处理者都实现了抽象处理者接口,并根据自身的业务逻辑来判断是否能够处理请求。如果能够处理,则处理请求;如果不能处理,则将请求传递给下一个处理者。

在主函数中,我们创建了具体的处理者对象,并通过设置处理链的方式将它们连接起来。然后创建了不同的请求,并通过第一个处理者来处理请求。输出结果为:

1
2
3
4
ConcreteHandlerA 处理了请求
ConcreteHandlerB 处理了请求
ConcreteHandlerC 处理了请求
无处理者能够处理该请求

这个示例展示了职责链模式的基本结构和使用方法,通过使用职责链模式,我们可以将请求的发送者和接收者解耦,使得请求的发送者不需要知道哪个对象能够处理请求。同时,我们可以动态地改变处理链,增加或者删除处理者,提高代码的灵活性和可扩展性。