Design Pattern-20. Chain of Responsibility Pattern

Design Pattern-20. Chain of Responsibility Pattern

One sentence summary

Allow multiple objects to have the opportunity to process the request, thereby avoiding the coupling relationship between the sender and receiver of the request. Connect these objects into a chain and pass the request along the chain until an object handles it.

demand

The company s approval is usually subject to the approval of the group leader, manager, director, and general manager. So how to use code to implement such a logic?

Code V1.0

The code of the manager class does not conform to the single responsibility principle and the open-closed principle.

static func main () { let jingli = Manager (name: " " ) let officer = Manager (name: "director" ) let officers = Manager (name: "GM" ) let request = Request () request.requestType = "Salary increase" request.requestContent = "Small dishes request a salary increase" request.number = 1000 jingli.getResult(managerLevel: "Manager" , request: request) officer.getResult(managerLevel: "Director" , request: request) officers.getResult(managerLevel: "General Manager" , request: request) let request2 = Request () request2.requestType = "leave" request2.requestContent = "dishes leave request" request2.number = . 3 jingli.getResult(managerLevel: "Manager" , request: request2) officer.getResult(managerLevel: "Director" , request: request2) officers.getResult(managerLevel: "General Manager" , request: request2) } class Request { var requestType = "" var requestContent = "" var number = 0 } class Manager { let name: String init ( name : String ) { self .name = name } func getResult ( managerLevel : String , request : Request ) { if managerLevel == "Manager" { if request.requestType == " Please leave" , request.number <= 2 { print ( " \(name) : \(request.requestContent ) Number \(request.number) is approved" ) } else { print ( " \(name) : \(request.requestContent) quantity \(request.number) I have no right to process" ) } } else if managerLevel == "Director" { if request.requestType == " Please leave" , request.number <= 5 { print ( " \(name) : \(request.requestContent) number \(request.number) approved " ) } else { print ( " \(name) : \(request.requestContent) quantity \(request.number) I have no right to process" ) } } else if managerLevel == "General Manager" { if request.requestType == " Please leave" { print ( " \(name) : \(request.requestContent) quantity \(request.number) approved" ) } else if request.requestType == "Salary increase" , request.number <= 500 { print ( " \(name) : \(request.requestContent) quantity \(request.number) approved" ) } else if request.requestType == "Salary increase" , request.number > 500 { print ( " \(name) : \(request.requestContent) number \(request.number) let's talk about it again" ) } } } } Copy code

Chain of Responsibility Pattern Sample Code

When the current instance of a class cannot be processed, it can be handed over to the next instance of the class for processing.

static func main () { let handler1 = ConcreteHandler1 () let handler2 = ConcreteHandler2 () let handler3 = ConcreteHandler3 () handler1.successor = handler2 handler2.successor = handler3 let requests = [ 2 , 8 , 11 , 14 , 21 , 23 , 5 , 30 , 40 ] for item in requests { handler1.handleRequest(request: item) } } protocol Handler { var successor: Handler ? { set get } func handleRequest ( request : Int ) } class ConcreteHandler1 : Handler { var successor: Handler ? func handleRequest ( request : Int ) { if request >= 0 , request < 10 { print ( " \( Self . self ) handling request \(request) " ) } else { successor ? .handleRequest(request: request) } } } class ConcreteHandler2 : Handler { var successor: Handler ? func handleRequest ( request : Int ) { if request >= 10 , request < 20 { print ( " \( Self . self ) processing request \(request) " ) } else { successor ? .handleRequest(request: request) } } } class ConcreteHandler3 : Handler { var successor: Handler ? func handleRequest ( request : Int ) { if request >= 20 , request < 30 { print ( " \( Self . self ) handling request \(request) " ) } else { successor ? .handleRequest(request: request) } } } Copy code

Code V2.0

Use the chain of responsibility model to achieve this requirement.

static func main () { let jingli = CommonManager (name: "Manager" ) let officer = Majordomo (name: "Director" ) let officerngli = GeneralManager (name: "General Manager" ) jingli.superior = officer officer.superior = officer let request = Request () request.requestType = "Salary increase" request.requestContent = "Small dishes request a salary increase" request.number = 1000 jingli.requestApplications(request: request) let request2 = Request () request2.requestType = "leave" request2.requestContent = "dishes leave request" request2.number = . 3 jingli.requestApplications(request: request2) } protocol Manager { var name: String { set get } var superior: Manager ? { set get } func requestApplications ( request : Request ) } class Request { var requestType = "" var requestContent = "" var number = 0 } class CommonManager : Manager { var name: String var superior: Manager ? init ( name : String ) { self .name = name } func requestApplications ( request : Request ) { if request.requestType == "Please leave" , request.number <= 2 { print ( " \(name) : \(request.requestContent) quantity \(request.number) approved" ) } else { superior ? .requestApplications(request: request) } } } class Majordomo : Manager { var name: String var superior: Manager ? init ( name : String ) { self .name = name } func requestApplications ( request : Request ) { if request.requestType == "please leave" , request.number <= 5 { print ( " \(name) : \(request.requestContent) quantity \(request.number) approved" ) } else { superior ? .requestApplications(request: request) } } } class GeneralManager : Manager { var name: String var superior: Manager ? init ( name : String ) { self .name = name } func requestApplications ( request : Request ) { if request.requestType == "Please leave" { print ( " \(name) : \(request.requestContent) number \(request.number) approved" ) } else if request.requestType == "Salary increase" , request.number <= 500 { print ( " \(name) : \(request.requestContent) quantity \(request.number) approved" ) } else if request.requestType == "Salary increase" , request.number > 500 { print ( " \(name) : \(request.requestContent) number \(request.number) let's talk about it again" ) } } } Copy code

Advantages of the chain of responsibility model

  • When a customer submits a request, the request will be passed along the chain until there is an object to handle it.
  • Neither the receiver nor the sender has clear information about the other party, and the objects in the chain do not know the structure of the chain. The interconnection of objects can be simplified, and each object only needs to maintain a reference to its successor instead of maintaining references to all successors.