[go] 责任链模式

news/2024/5/19 11:49:51 标签: golang, 责任链模式, 算法

责任链模式

责任链模式是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。

模型说明

  • Handler:声明了所有具体处理者的通用接口。该接口通常仅包含单个方法用于请求处理,但有时其还包含一个设置链上下个处理者的方法。

  • BaseHandler:是一个可选的类,你可以将所有处理者共用的样本代码放置在其中。

  • 通常情况下,该类中定义了一个保存对于下个处理者引用的成员变量。客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。该类还可以实现默认的处理行为:确定下个处理者存在后再将请求传递给它。

  • ConcreteHandlers:包含处理请求的实际代码。每个处理者接收到请求后,都必须决定是否进行处理,以及是否沿着链传递请求。

  • 处理者通常是独立且不可变的,需要通过构造函数一次性地获得所有必要的数据。

  • Client:可根据程序逻辑一次性或者动态地生成链。值得注意的是,请求可发送给脸上的任意一个处理者,而非必须是第一个处理者。

优缺点

1.优点

  • 你可以控制请求处理的顺序。
  • *单一职责原则:*你可对发起操作和执行操作的类进行解耦。
  • *开闭原则:*你可以在不更改现有代码的情况下在程序中新增处理者。

2.缺点

  • 部分请求可能未被处理。

使用场景

  • 当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式
  • 当必须按顺序执行多个处理者时, 可以使用该模式。
  • 如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式

参考代码

// patient.go 病人
package main

type Patient struct {
	name              string
	registrationDone  bool
	doctorCheckUpDone bool
	medicineDone      bool
	paymentDone       bool
}

// department.go 处理者接口
package main

type Department interface {
	execute(*Patient)
	setNext(Department)
}

// reception.go 具体处理者
package main

import "fmt"

type Reception struct {
	next Department
}

func (r *Reception) execute(p *Patient) {
	if p.registrationDone {
		fmt.Println("Patient registration already done")
		r.next.execute(p)
		return
	}
	fmt.Println("Reception registering patient")
	p.registrationDone = true
	r.next.execute(p)
}

func (r *Reception) setNext(next Department) {
	r.next = next
}

// doctor.go 具体处理者
package main

import "fmt"

type Doctor struct {
	next Department
}

func (d *Doctor) execute(p *Patient) {
	if p.doctorCheckUpDone {
		fmt.Println("Doctor checkup already done")
		d.next.execute(p)
		return
	}
	fmt.Println("Doctor checking patient")
	p.doctorCheckUpDone = true
	d.next.execute(p)
}

func (d *Doctor) setNext(next Department) {
	d.next = next
}

// medical.go 具体处理者
package main

import "fmt"

type Medical struct {
	next Department
}

func (m *Medical) execute(p *Patient) {
	if p.medicineDone {
		fmt.Println("Medicine already given to patient")
		m.next.execute(p)
		return
	}
	fmt.Println("Medical giving medicine to patient")
	p.medicineDone = true
	m.next.execute(p)
}

func (m *Medical) setNext(next Department) {
	m.next = next
}

// medical.go 具体处理者
package main

import "fmt"

type Medical struct {
	next Department
}

func (m *Medical) execute(p *Patient) {
	if p.medicineDone {
		fmt.Println("Medicine already given to patient")
		m.next.execute(p)
		return
	}
	fmt.Println("Medical giving medicine to patient")
	p.medicineDone = true
	m.next.execute(p)
}

func (m *Medical) setNext(next Department) {
	m.next = next
}

// main.go 客户端代码
package main

func main() {
	cashier := &Cashier{}

	//Set next for medical department
	medical := &Medical{}
	medical.setNext(cashier)

	//Set next for doctor department
	doctor := &Doctor{}
	doctor.setNext(medical)

	//Set next for reception department
	reception := &Reception{}
	reception.setNext(doctor)

	patient := &Patient{name: "abc"}
	//Patient visiting
	reception.execute(patient)
}

output:

Reception registering patient
Doctor checking patient
Medical giving medicine to patient
Cashier getting money from patient patient

http://www.niftyadmin.cn/n/5334518.html

相关文章

Debian 10.13.0 安装图解

引导和开始安装 这里直接回车确认即可,选择图形化安装方式。 选择语言 这里要区分一下,当前选中的语言作为安装过程中安装器所使用的语言,这里我们选择中文简体。不过细心的同学可能发现,当你选择安装器语言之后,后续安…

FPGA物理引脚,原理(Pacakge and pinout)-认知3

画FPGA芯片引脚封装图(原理),第一是参考开发板(根据一下描述了解总览),第二是研究Datasheet. ASCII Pinout File Zynq-7000 All Programmable SoC Packaging and Pinout(UG585) 1. Pacakge overview 1.1&#xff0…

9 | Tensorflow中的batch批处理

TensorFlow支持批处理(batch processing)。批处理是指同时处理多个样本或数据点而不是单个样本。在深度学习中,批处理通常用于提高训练的效率和稳定性。 在TensorFlow中,可以使用tf.data.Dataset API来设置和处理批处理数据。这允许以批处理的方式加载和处理数据,适用于训…

用Pytorch实现线性回归模型

目录 回顾Pytorch实现步骤1. 准备数据2. 设计模型class LinearModel代码 3. 构造损失函数和优化器4. 训练过程5. 输出和测试完整代码 练习 回顾 前面已经学习过线性模型相关的内容,实现线性模型的过程并没有使用到Pytorch。 这节课主要是利用Pytorch实现线性模型。…

Spring Boot 优雅实现统一数据返回格式+统一异常处理+统一日志处理

在我们的项目开发中,我们都会对数据返回格式进行统一的处理,这样可以方便前端人员取数据,当然除了正常流程的数据返回格式需要统一以外,我们也需要对异常的情况进行统一的处理,以及项目必备的日志。 1. 统一返回格式 …

服务器工作环境要求

在开展网站服务之前,合适的服务器工作环境是必不可少的。服务器工作环境指需要一定的软硬件条件来保障服务器可以正常地运转和提供高效率的服务。在这篇文章中,我们将会详细讲解服务器工作环境所需的要素。 一、硬件要求 服务器硬件方面包括了基本的电…

PGSQL主键序列

PostgreSQL和 MySQL数据库还是有一定的区别。 下面了解一下 PGSQL的主键序列。 一、主键 1、系统自带主键序列 在 PostgreSQL 中,GENERATED BY DEFAULT 和 GENERATED ALWAYS 是用于定义自动生成的列(Generated Column)的选项。一般可作用…

2024-01-18 在Android Studio中,可以通过修改build.gradle文件(位于你的应用模块目录下)来自定义生成的APK名称

一、在Android Studio中,可以通过修改build.gradle文件(位于你的应用模块目录下)来自定义生成的APK名称,在build.gradle里面增加下面的代码 applicationVariants.all { variant ->variant.outputs.all {outputFileName "…