时间:2025-03-18 23:28
人气:
作者:admin
责任链模式(Chain of Responsibility Pattern)允许开发者将请求沿着链进行发送,直到其中一个处理者对象对其进行处理。
责任链模式的角色说明:
package chainofresponsibility
import "fmt"
// 基础处理者类 Patient 病人类
type Patient struct {
Name string
RegistrationDone bool
ClinicCheckUpDone bool
DrugstoreDone bool
PaymentDone bool
}
// 处理者接口 department 科室接口
type department interface {
Operate(*Patient)
SetNext(department)
}
// 具体处理者, 前台类
type Reception struct {
next department
}
func (r *Reception) Operate(p *Patient) {
if p.RegistrationDone {
fmt.Println("Patient already registered")
r.next.Operate(p)
return
}
fmt.Println("Reception registering patient")
p.RegistrationDone = true
r.next.Operate(p)
}
func (r *Reception) SetNext(next department) {
r.next = next
}
// 具体处理者, 诊室类
type Clinic struct {
next department
}
func (c *Clinic) Operate(p *Patient) {
if p.ClinicCheckUpDone {
fmt.Println("Patient already checked up")
c.next.Operate(p)
return
}
fmt.Println("Clinic checking up patient")
p.ClinicCheckUpDone = true
c.next.Operate(p)
}
func (c *Clinic) SetNext(next department) {
c.next = next
}
// 具体处理者, 药房类
type Drugstore struct {
next department
}
func (d *Drugstore) Operate(p *Patient) {
if p.DrugstoreDone {
fmt.Println("Patient already drugstored")
d.next.Operate(p)
return
}
fmt.Println("Drugstore giving medicine to patient")
p.DrugstoreDone = true
d.next.Operate(p)
}
func (d *Drugstore) SetNext(next department) {
d.next = next
}
// 具体处理者, 收银台类
type Cashier struct {
next department
}
func (c *Cashier) Operate(p *Patient) {
if p.PaymentDone {
fmt.Println("Patient already paid")
return
}
fmt.Println("Cashier taking money from patient")
p.PaymentDone = true
}
func (c *Cashier) SetNext(next department) {
c.next = next
}
测试代码
package chainofresponsibility
import (
"testing"
)
func TestChainOfResponsibility(t *testing.T) {
cashier := &Cashier{}
drugstore := &Drugstore{}
clinic := &Clinic{}
reception := &Reception{}
reception.SetNext(clinic)
clinic.SetNext(drugstore)
drugstore.SetNext(cashier)
reception.Operate(&Patient{Name: "Alan"})
}
from abc import ABCMeta, abstractmethod
class Patient:
"""基础处理类"""
def __init__(
self,
name: str,
is_registration: bool = False,
is_clinic_check: bool = False,
is_drugstore: bool = False,
is_payment: bool = False,
):
self.name = name
self.is_registration = is_registration
self.is_clinic_check = is_clinic_check
self.is_drugstore = is_drugstore
self.is_payment = is_payment
class Department(metaclass=ABCMeta):
"""抽象基类, 科室接口"""
def __init__(self):
self.next: Department = None
@abstractmethod
def operate(self, patient: Patient):
pass
def set_next(self, depr):
if not issubclass(type(depr), Department):
raise Exception("Invalid Department")
self.next = depr
class Registration(Department):
"""具体处理类, 科室"""
def __init__(self):
super().__init__()
def operate(self, p: Patient):
if p.is_registration:
print(f"{p.name} is already registered")
self.next.operate(p)
return
print(f"{p.name} is registering")
p.is_registration = True
self.next.operate(p)
class Clinic(Department):
"""具体处理类, 诊室"""
def __init__(self):
super().__init__()
def operate(self, p: Patient):
if p.is_clinic_check:
print(f"{p.name} is already checked at the clinic")
self.next.operate(p)
return
print(f"{p.name} is checking clinic")
p.is_clinic_check = True
self.next.operate(p)
class DrugStore(Department):
"""具体处理类, 药房"""
def __init__(self):
super().__init__()
def operate(self, p: Patient):
if p.is_drugstore:
print(f"{p.name} is already given drugs")
self.next.operate(p)
return
print(f"{p.name} is checking drugstore")
p.is_drugstore = True
self.next.operate(p)
class Cashier(Department):
"""具体处理类, 收费处"""
def __init__(self):
super().__init__()
def operate(self, p: Patient):
if p.is_payment:
print(f"{p.name} is already paid")
return
print(f"{p.name} is paying")
p.is_payment = True
print(f"{p.name} is being released")
if __name__ == "__main__":
registration = Registration()
clinic = Clinic()
drugstore = DrugStore()
cashier = Cashier()
registration.set_next(clinic)
clinic.set_next(drugstore)
drugstore.set_next(cashier)
patient = Patient("John")
registration.operate(patient)
本文来自博客园,作者:花酒锄作田,转载请注明原文链接:https://www.cnblogs.com/XY-Heruo/p/18780072
上一篇:依赖倒置 DIP、依赖注入 DI、控制反转 IoC 和工厂
下一篇:访问者模式