文章目录
- [1 概念](#1 概念)
-
- [1.1 角色](#1.1 角色)
- [1.2 类图](#1.2 类图)
- [2. 代码示例](#2. 代码示例)
-
- [2.1 设计](#2.1 设计)
- [2.2 代码](#2.2 代码)
- [2.3 类图](#2.3 类图)
1 概念
责任链(Chain of Responsibility)是指将客户端请求处理的不同职责对象组成请求处理链。
客户端只需要将请求交付到该链上,而不需要关心链上含有哪些对象。请求处理链上的对象收到请求后,执行自身业务职责,并将该请求传递到下一个链节点。由于客户端不需要了解责任链上节点对象的具体类型,大大降低了客户端与请求处理对象之间的耦合度。
1.1 角色
抽象处理者(Handler):包含抽象处理方法和一个后续处理者。
具体处理者(ConcreteHandler):实现抽象处理者的处理方法。
请求发送者(Client):向处理者发送请求。
1.2 类图
Client Handler #successor:Handler +handleRequest(request:Request) ConcreteHandlerA +handleRequest(request:Request) ConcreteHandlerB +handleRequest(request:Request)
2. 代码示例
2.1 设计
- 定义一个抽象处理者
Handler
- 定义实际处理者
ConcreteHandlerA
、ConcreteHandlerB
- 它们实现了抽象处理者
Handler
- 它继承了另一个处理者(下一个处理者)
- 它的
Option()
方法执行它的责任 - 它的
handleRequest()
方法组装责任链并执行它的责任
- 它们实现了抽象处理者
- 调用
- 实例化三个实际处理者
- 使用
handleRequest()
方法执行责任链
2.2 代码
go
package main
import (
"fmt"
)
// 定义抽象处理者
type Handler interface {
handleRequest() string
}
// 定义实际处理者A
type ConcreteHandlerA struct {
name string
next Handler
}
//定义一个方法模拟实际处理者A的处理过程
func (c *ConcreteHandlerA) Option() {
fmt.Println("执行:" + c.name)
}
//定义一个方法,完成它的处理后,交给下一个实际处理者
func (c *ConcreteHandlerA) handleRequest() string {
c.Option()
if c.next != nil {
return c.next.handleRequest()
}
return ""
}
// 定义实际处理者B(情况和A相同)
type ConcreteHandlerB struct {
name string
next Handler
}
func (c *ConcreteHandlerB) Option() {
fmt.Println("执行:" + c.name)
}
func (c *ConcreteHandlerB) handleRequest() string {
c.Option()
if c.next != nil {
return c.next.handleRequest()
}
return ""
}
//定义一个函数,生产处理者
func NewHandler(name string, next Handler, kind string) (handler Handler, err error) {
switch kind {
case "A":
handler = &ConcreteHandlerA{
name: name,
next: next,
}
return handler, nil
case "B":
handler = &ConcreteHandlerB{
name: name,
next: next,
}
return handler, nil
default:
return nil, err
}
}
func main() {
//实例化3个实际处理者
handlerA1, _ := NewHandler("handlerA1", nil, "A")
handlerA2, _ := NewHandler("handlerA2", handlerA1, "A")
handlerB1, _ := NewHandler("handlerB1", handlerA2, "B")
//使用handleRequest方法依次处理(处理过程我们不可见,但是可以通断点过调试看到)
r := handlerB1.handleRequest()
fmt.Println(r)
}
- 执行结果
shell
执行:handlerB1
执行:handlerA2
执行:handlerA1
2.3 类图
Client <<interface>> Handler +handleRequest() : string ConcreteHandlerA +name:string +next:Handler +handleRequest() : string +Option() ConcreteHandlerB +name:string +next:Handler +handleRequest() : string +Option()