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


    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 代码

    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)
    }
    
    
    • 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
    • 执行结果
    执行:handlerB1
    执行:handlerA2
    执行:handlerA1
    
    • 1
    • 2
    • 3

    2.3 类图

    Client
    «interface»
    Handler
    +handleRequest() : string
    ConcreteHandlerA
    +name:string
    +next:Handler
    +handleRequest() : string
    +Option()
    ConcreteHandlerB
    +name:string
    +next:Handler
    +handleRequest() : string
    +Option()

    在这里插入图片描述

  • 相关阅读:
    Mac 苹果系统使用nvm use 切换node版本号
    翻阅必备----Java窗口组件,容器,布局,监听,事件 API大全
    基于SSM的鲜花商城系统【附源码文档】
    构建自己的插件框架:第 1 部分
    八、T100应付管理系统之员工费用报销管理篇
    看完才发现饼图插入图片so easy!
    最近公共祖先(LCA)学习笔记 | P3379 【模板】最近公共祖先(LCA)题解
    可拓展的低代码全栈框架
    J2EE项目部署与发布(Windows版本)
    Numpy数组计算实训
  • 原文地址:https://blog.csdn.net/xingzuo_1840/article/details/131822653