package chain import ( "errors" "fmt" ) const ( PatientStatusStart = iota + 1 // 状态:开始看病 PatientStatusReception // 状态:已挂号 PatientStatusClinic // 状态:已看诊 PatientStatusCashier // 状态:已缴费 PatientStatusPharmacy // 状态:已拿药 ) type Patient struct { name string // 姓名 status int // 状态 } type PatientHandler interface { Execute(patient *Patient) error // 处理链路传递 SetNext(handler PatientHandler) PatientHandler // 设置下一个处理者 Do(patient *Patient) error // 执行处理逻辑 } // BaseHandler 充当抽象类的角色 // Do 方法无法抽象出来,故不实现 type BaseHandler struct { nextHandler PatientHandler // 下一个处理者 } func (h *BaseHandler) Execute(patient *Patient) error { if patient == nil { return nil } // 因为 Do 方法未实现,这里无法调用自身的 Do // 实际调用链路时,需要为初始流程定义一个起始执行者 if h.nextHandler != nil { if err := h.nextHandler.Do(patient); err != nil { // 调用下一个处理者的Do方法 return err } return h.nextHandler.Execute(patient) // 调用下一个处理者的Execute方法 } return nil } func (h *BaseHandler) SetNext(handler PatientHandler) PatientHandler { h.nextHandler = handler return handler } type Reception struct { BaseHandler // 嵌入BaseHandler以实现链式调用 } func (r *Reception) Do(patient *Patient) error { if patient.status > PatientStatusStart { return errors.New("患者已经挂号") } fmt.Printf("挂号处为患者 %s 挂号\n", patient.name) patient.status = PatientStatusReception // 更新患者状态为已挂号 return nil } type Clinic struct { BaseHandler // 嵌入BaseHandler以实现链式调用 } func (c *Clinic) Do(patient *Patient) error { if patient.status == PatientStatusStart { return errors.New("患者还未挂号") } if patient.status > PatientStatusReception { return errors.New("患者已经完成医生诊断") } fmt.Printf("医生为患者 %s 进行诊断\n", patient.name) patient.status = PatientStatusClinic // 更新患者状态为已看诊 return nil } type Cashier struct { BaseHandler // 嵌入BaseHandler以实现链式调用 } func (c *Cashier) Do(patient *Patient) error { if patient.status < PatientStatusClinic { return errors.New("患者还未看诊") } if patient.status > PatientStatusClinic { return errors.New("患者已经完成缴费") } fmt.Printf("收费处收取患者 %s 的费用\n", patient.name) patient.status = PatientStatusCashier // 更新患者状态为已缴费 return nil } type Pharmacy struct { BaseHandler // 嵌入BaseHandler以实现链式调用 } func (p *Pharmacy) Do(patient *Patient) error { if patient.status < PatientStatusCashier { return errors.New("患者还未缴费") } if patient.status > PatientStatusCashier { return errors.New("患者已经领取药物") } fmt.Printf("药房为患者 %s 配药\n", patient.name) patient.status = PatientStatusPharmacy // 更新患者状态为已拿药 return nil } type HospitalChainHandler struct { BaseHandler // 嵌入BaseHandler以实现链式调用 } // Do 该方法可无逻辑,如需执行逻辑则需要重写 Execute 来确保执行 func (h *HospitalChainHandler) Do(patient *Patient) error { fmt.Printf("患者 %s 开始看病\n", patient.name) patient.status = PatientStatusStart // 更新患者状态为开始看病 return nil } // Execute 重写该方法以确保责任链的执行顺序 func (h *HospitalChainHandler) Execute(patient *Patient) error { if patient == nil { return nil } if err := h.Do(patient); err != nil { // 首先执行自己的Do方法 return err } return h.BaseHandler.Execute(patient) // 然后继续责任链 }