《golang设计模式》第三部分·行为型模式-01-责任链模式(Chain of Responsibility)

文章目录

  • [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
  • 定义实际处理者ConcreteHandlerAConcreteHandlerB
    • 它们实现了抽象处理者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()


相关推荐
IT技术分享社区13 小时前
架构入门系列:在线二手交易平台技术选型指南
程序员·架构
Dobby_0515 小时前
【Go】C++ 转 Go 第(四)天:结构体、接口、反射、标签 | 面向对象编程
vscode·golang·1024程序员节
一语长情15 小时前
多线程同步实战指南:Python、Java与Go的等待之道
后端·面试·架构
pccai-vip18 小时前
架构论文《论系统超融合架构的设计与应用》
架构
怪力乌龟18 小时前
Go语言数组和切片
开发语言·后端·golang
Yeats_Liao18 小时前
Go Web 编程快速入门 08 - JSON API:编码、解码与内容协商
后端·golang·json
红宝村村长18 小时前
Golang交叉编译到Android上运行
android·开发语言·golang
虚行18 小时前
Go 编程基础
开发语言·后端·golang
脚踏实地的大梦想家18 小时前
【Go】P14 Go语言核心利器:全面解析结构体 (Struct)
开发语言·后端·golang
虚行18 小时前
Go学习资料整理
golang·区块链