Golang Chain of responsibilityPattern explanation and code examples
This pattern allows multiple objects to process requests without coupling the sender class with the specific receiver class. The chain can be dynamically generated at runtime by any processor that follows the standard processor interface.
Concept example
Let's take a look at an example of a chain of responsibility model for hospital applications. There will be multiple departments in the hospital, such as:
- front desk
- doctor
- pharmacy
- Cash checkout
When patients come to visit, they will first go to the front desk, then see a doctor, get the medicine, and finally check out. That is, the patient needs to pass through a department chain, each department further transports the patient along the chain after completing its functions.
This mode is suitable for situations where multiple candidate options are used to handle the same request, for situations where the client does not want the client to select the receiver (because multiple objects can handle the request), and for situations where the client wants to decouple the client from the receiver. The client only needs the first element in the chain.
As in the example hospital, the first thing the patient goes to after arriving is the front desk. Then, based on the patient's current status, the front desk will point it to the next processor on the chain.
:Processor interface
package main type Department interface { execute(*Patient) setNext(Department) }
:Specific handler
package main import "fmt" // front desktype Reception struct { next Department } func (r *Reception) execute(p *Patient) { if { ("Patient registration already done") (p) } ("Reception registering patient") = true (p) } func (r *Reception) setNext(next Department) { = next }
:Specific handler
package main import "fmt" type Doctor struct { next Department } func (d *Doctor) execute(p *Patient) { if { ("Doctor checkup already done") (p) return } ("Doctor checking patient") = true (p) } func (d *Doctor) setNext(next Department) { = next }
:Specific handler
package main import "fmt" type Medical struct { next Department } func (m *Medical) execute(p *Patient) { if { ("Medicine already given to patient") (p) return } ("Medical giving medicine to patient") = true (p) } func (m *Medical) setNext(next Department) { = next }
:Specific handler
package main import "fmt" type Cashier struct { next Department } func (c *Cashier) execute(p *Patient) { if { ("Payment Done") } ("Cashier getting money from patient patient") } func (c *Cashier) setNext(next Department) { = next }
package main type Patient struct { name string registrationDone bool // Registration status doctorCheckUpDone bool // Is the doctor completed the examination medicineDone bool // Have you finished taking the medicine paymentDone bool // Have you paid}
:Client code
package main func main() { cashier := &Cashier{} // set next for medical department medical := &Medical{} (cashier) //Set next for doctor department doctor := &Doctor{} (medical) //Set next for reception department reception := &Reception{} (doctor) patient := &Patient{name: "abc"} //Patient visiting (patient) }
:Execution results
Reception registering patient
Doctor checking patient
Medical giving medicine to patient
Cashier getting money from patient patient
This is the article about the explanation and code examples of the Golang design model. For more related content of the Golang responsibility chain model, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!