GO设计模式——15、责任链模式(行为型)

目录

[责任链模式(Chain of Responsibility Pattern)](#责任链模式(Chain of Responsibility Pattern))

责任链模式的核心角色:

优缺点

使用场景

代码实现


责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链将请求的发送者和接收者解耦,并允许多个对象都有机会处理请求。通过为多个对象构成一个链,并将请求沿着这条链传递,直到有一个对象处理请求为止。在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,请求会自动进行传递。所以责任链将请求的发送者和请求的处理者解耦了。

责任链模式的核心角色

  • 抽象处理者(Handler):定义了处理请求的接口,通常包含一个指向下一个处理者的引用。
  • 具体处理者(Concrete Handler):实现了抽象处理者接口,负责处理请求,如果自己不能处理,则将请求传递给下一个处理者

优缺点

(1)优点:

  • 降低耦合度。它将请求的发送者和接收者解耦。
  • 简化了对象。使得对象不需要知道链的结构。
  • 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
  • 增加新的请求处理类很方便。

(2)缺点:

  • 不能保证请求一定被接收。
  • 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
  • 可能不容易观察运行时的特征,有碍于除错。

使用场景

  • 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
  • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  • 可动态指定一组对象处理请求。

代码实现

Go 复制代码
package main

// 请假审批系统,员工可以提交请假申请,申请会依次经过部门经理、人事部门和总经理的审批。
// 如果其中任何一个审批者同意了请假申请,审批流程就结束,否则继续传递给下一个审批者。
import "fmt"

// 抽象处理者:审批者接口
type Approver interface {
    SetNext(approver Approver)
    ProcessRequest(request Request)
}

// 具体处理者:部门经理
type DepartmentManager struct {
    next Approver
}

func (dm *DepartmentManager) SetNext(approver Approver) {
    dm.next = approver
}

func (dm *DepartmentManager) ProcessRequest(request Request) {
    if request.Type == "Leave" && request.Amount <= 3 {
       fmt.Println("Department Manager approved the request.")
    } else if dm.next != nil {
       dm.next.ProcessRequest(request)
    }
}

// 具体处理者:人事部门
type HRDepartment struct {
    next Approver
}

func (hr *HRDepartment) SetNext(approver Approver) {
    hr.next = approver
}

func (hr *HRDepartment) ProcessRequest(request Request) {
    if request.Type == "Leave" && request.Amount <= 7 {
       fmt.Println("HR Department approved the request.")
    } else if hr.next != nil {
       hr.next.ProcessRequest(request)
    }
}

// 具体处理者:总经理
type GeneralManager struct {
    next Approver
}

func (gm *GeneralManager) SetNext(approver Approver) {
    gm.next = approver
}

func (gm *GeneralManager) ProcessRequest(request Request) {
    if request.Type == "Leave" && request.Amount <= 10 {
       fmt.Println("General Manager approved the request.")
    } else {
       fmt.Println("Request denied.")
    }
}

// 请求结构体
type Request struct {
    Type   string
    Amount int
}

// 客户端代码
func main() {
    departmentManager := &DepartmentManager{}
    hrDepartment := &HRDepartment{}
    generalManager := &GeneralManager{}

    departmentManager.SetNext(hrDepartment)
    hrDepartment.SetNext(generalManager)

    request := Request{
       Type:   "Leave",
       Amount: 5,
    }

    departmentManager.ProcessRequest(request)
}
相关推荐
Rverdoser3 分钟前
RabbitMQ的基本概念和入门
开发语言·后端·ruby
小白不太白9501 小时前
设计模式之 模板方法模式
java·设计模式·模板方法模式
Tech Synapse1 小时前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端
.生产的驴1 小时前
SpringCloud OpenFeign用户转发在请求头中添加用户信息 微服务内部调用
spring boot·后端·spring·spring cloud·微服务·架构
微信-since811921 小时前
[ruby on rails] 安装docker
后端·docker·ruby on rails
色空大师1 小时前
23种设计模式
java·开发语言·设计模式
闲人一枚(学习中)1 小时前
设计模式-创建型-建造者模式
java·设计模式·建造者模式
博风2 小时前
设计模式:6、装饰模式(包装器)
设计模式
A_cot2 小时前
理解设计模式与 UML 类图:构建稳健软件架构的基石
microsoft·设计模式·简单工厂模式·工厂方法模式·uml
君败红颜2 小时前
设计模式之创建模式篇
设计模式