责任链模式属于行为设计模式
GoF定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
场景
1.在接收web请求时,需要进行参数验证。
2.在消费消息时,需要对消费到消息进行参数验证。
上述场景中,若参数验证比较复杂,责任链可以依次判断,后续若减少或者增加参数校验,会变得很容易。
责任链中的一个方法只专注判断一个参数,体现了单一职责的设计原则。
示例
支付单报关: 跨境电商,订单状态未付款变成已付款状态时,需要进行支付单报关
技术实现:
1.订阅订单的状态变化的消息
2.验证订单的参数
3.支付报关
实现的流程非常简单,不用责任链也可以实现。
1.需要校验的参数非常多
2.参数校验的逻辑非常复杂
3.参数的校验顺序经常改变
4.后续会增加需要校验的参数
5.后续会删除校验的参数
在以上的场景中,使用责任链可以让代码变得容易维护和扩展。
实现
基础处理
go
// 处理器接口
type Handler interface {
SetNext(handler Handler) Handler
Handle(request *RequestParam, response *ResponseResult)
}
// 基础处理器
type BaseHandler struct {
next Handler
}
func (h *BaseHandler) SetNext(handler Handler) Handler {
h.next = handler
return handler
}
func (h *BaseHandler) Handle(request *RequestParam, response *ResponseResult) {
if h.next != nil {
h.next.Handle(request, response)
}
}
BaseHandler
实现基础处理。需要校验的字段可以基于这个进行扩展。
next
来标识下一步的操作,使用过gi内框架开发程序的朋友一定马上联想到了中间件。
责任链的运用非常广泛,在各种工作流软件及中间件组件中都会遇到。
字段处理器
订单号验证处理器
go
// 订单号验证处理器
type OrderNoHandler struct {
BaseHandler
}
func NewOrderNoHandler() *OrderNoHandler {
return &OrderNoHandler{}
}
func (h *OrderNoHandler) Handle(request *RequestParam, response *ResponseResult) {
if request.OrderNo == "" {
response.Success = false
response.Message = "订单号不能为空"
return
}
fmt.Println("订单号证通过")
h.BaseHandler.Handle(request, response)
}
支付人验证处理器
go
type PaymentNameHandler struct {
BaseHandler
}
func NewPaymentNameHandler() *PaymentNameHandler {
return &PaymentNameHandler{}
}
func (h *PaymentNameHandler) Handle(request *RequestParam, response *ResponseResult) {
if request.PaymentName == "" {
response.Success = false
response.Message = "支付宝人不能为空"
return
}
fmt.Println("支付人验证通过")
h.BaseHandler.Handle(request, response)
}
支付人身份证验证器
go
// 支付人身份证验证处理器
type PaymentIdCardHandler struct {
BaseHandler
}
func NewPaymentIdCardHandler() *PaymentIdCardHandler {
return &PaymentIdCardHandler{}
}
func (h *PaymentIdCardHandler) Handle(request *RequestParam, response *ResponseResult) {
if request.PaymentIdCard == "" {
response.Success = false
response.Message = "支付人身份证不能为空"
return
}
fmt.Println("支付人身份证验证通过")
h.BaseHandler.Handle(request, response)
}
支付流水号验证器
go
// 支付流水号验证处理器
type TradeNoHandler struct {
BaseHandler
}
func NewTradeNoHandler() *TradeNoHandler {
return &TradeNoHandler{}
}
func (h *TradeNoHandler) Handle(request *RequestParam, response *ResponseResult) {
if request.TradeNo == "" {
response.Success = false
response.Message = "支付流水号不能为空"
return
}
fmt.Println("支付流水号验证通过")
h.BaseHandler.Handle(request, response)
}
如何使用
go
// 支付报关处理器
type DeclareHandler struct {
BaseHandler
}
func NewDeclareHandler() *DeclareHandler {
return &DeclareHandler{}
}
func (h *DeclareHandler) Handle(request *RequestParam, response *ResponseResult) {
// 支付报关
response.Success = true
response.Message = "支付单报关成功"
}
go
// 创建责任链
orderNoHandler := NewOrderNoHandler()
// 组装责任链
orderNoHandler.SetNext(NewPaymentNameHandler()).
SetNext(NewPaymentIdCardHandler()).
SetNext(NewTradeNoHandler()).
SetNext(NewDeclareHandler())
完整示例
go
package main
import "fmt"
// 请求和响应结构
type RequestParam struct {
OrderNo string
PaymentName string
PaymentIdCard string
TradeNo string
}
type ResponseResult struct {
Success bool
Message string
}
// 处理器接口
type Handler interface {
SetNext(handler Handler) Handler
Handle(request *RequestParam, response *ResponseResult)
}
// 基础处理器
type BaseHandler struct {
next Handler
}
func (h *BaseHandler) SetNext(handler Handler) Handler {
h.next = handler
return handler
}
func (h *BaseHandler) Handle(request *RequestParam, response *ResponseResult) {
if h.next != nil {
h.next.Handle(request, response)
}
}
// 订单号验证处理器
type OrderNoHandler struct {
BaseHandler
}
func NewOrderNoHandler() *OrderNoHandler {
return &OrderNoHandler{}
}
func (h *OrderNoHandler) Handle(request *RequestParam, response *ResponseResult) {
if request.OrderNo == "" {
response.Success = false
response.Message = "订单号不能为空"
return
}
fmt.Println("订单号证通过")
h.BaseHandler.Handle(request, response)
}
// 支付人验证处理器
type PaymentNameHandler struct {
BaseHandler
}
func NewPaymentNameHandler() *PaymentNameHandler {
return &PaymentNameHandler{}
}
func (h *PaymentNameHandler) Handle(request *RequestParam, response *ResponseResult) {
if request.PaymentName == "" {
response.Success = false
response.Message = "支付宝人不能为空"
return
}
fmt.Println("支付人验证通过")
h.BaseHandler.Handle(request, response)
}
// 支付人身份证验证处理器
type PaymentIdCardHandler struct {
BaseHandler
}
func NewPaymentIdCardHandler() *PaymentIdCardHandler {
return &PaymentIdCardHandler{}
}
func (h *PaymentIdCardHandler) Handle(request *RequestParam, response *ResponseResult) {
if request.PaymentIdCard == "" {
response.Success = false
response.Message = "支付人身份证不能为空"
return
}
fmt.Println("支付人身份证验证通过")
h.BaseHandler.Handle(request, response)
}
// 支付流水号验证处理器
type TradeNoHandler struct {
BaseHandler
}
func NewTradeNoHandler() *TradeNoHandler {
return &TradeNoHandler{}
}
func (h *TradeNoHandler) Handle(request *RequestParam, response *ResponseResult) {
if request.TradeNo == "" {
response.Success = false
response.Message = "支付流水号不能为空"
return
}
fmt.Println("支付流水号验证通过")
h.BaseHandler.Handle(request, response)
}
// 支付报关处理器
type DeclareHandler struct {
BaseHandler
}
func NewDeclareHandler() *DeclareHandler {
return &DeclareHandler{}
}
func (h *DeclareHandler) Handle(request *RequestParam, response *ResponseResult) {
// 支付报关
response.Success = true
response.Message = "支付单报关成功"
}
func main() {
// 创建责任链
orderNoHandler := NewOrderNoHandler()
// 组装责任链
orderNoHandler.SetNext(NewPaymentNameHandler()).
SetNext(NewPaymentIdCardHandler()).
SetNext(NewTradeNoHandler()).
SetNext(NewDeclareHandler())
// 创建请求
request := &RequestParam{
PaymentName: "张三丰",
PaymentIdCard: "989987200110100093",
TradeNo: "TR20250101080000",
OrderNo: "OR20250101080000",
}
// 处理请求
response := &ResponseResult{}
orderNoHandler.Handle(request, response)
// 输出结果
fmt.Println("结果:", response.Message)
}
总结
责任链模式优点:
1.动态分配职责 :灵活处理请求
2.增强扩展性 :支持新增处理者而无需修改现有代码
3.职责明确 :代码清晰易维护
4.灵活处理请求 :支持多步骤、多条件的请求处理
5.减少代码重复 :避免冗余逻辑
6.支持优先级处理:根据需求调整链的顺序
怎样?那么多的好处,还不在你的项目中运用起来。