"Reprint" Responsibility chain Mode
In the book "Java and Patterns" of Dr. Shanhong, this is how the responsibility chain (Chain of Responsibility) pattern is described:
The responsibility chain pattern is an object's behavior pattern. In the chain of responsibility, many objects are linked together by each object's reference to its next generation. The request is passed on this chain until an object on the chain decides to process the request. The client making this request does not know which object on the chain is ultimately processing the request, which allows the system to reorganize and assign responsibilities dynamically without affecting the client.
Talking about the flowers from the drums
Drumming is a lively and tense drinking game. In the banquet of guests seated in turn, by a person drumming, drums and the place of the flowers are separated, to show just. When the drums begin, the bouquet begins to pass, the drums fall, and if the bouquet is in someone's hand, the person will have to drink.
For example, Jiamu, Jia-Pardon, Jia Zheng, Jia Baoyu and Baoyu are five of the flowers to participate in the drum-spreading game, they form a ring chain. The drum player passes the flowers to Jiamu and begins the flower-spreading game. Flowers from Jiamu to Jia pardon, from Jia pardon to Jia Zheng, from Jia Zheng to Jia Baoyu, and Jia Baoyu passed to Baoyu, from Baoyu back to Jiamu, so reciprocating, as shown. When the drums stop, people with flowers in their hands will have to enforce the prohibition.
It is the application of the responsibility chain mode to pass the flower drum. A chain of responsibility may be a line, a chain, or part of a tree structure.
The structure of the responsibility chain model
The simplest implementation of a chain of responsibility model is used below.
The roles involved in the responsibility chain model are as follows:
Abstract Processor (Handler) Role: defines an interface for processing requests. If necessary, the interface can define a method to set and return a reference to the home. This role is typically implemented by a Java abstract class or Java interface. The aggregation relationship of the handler class gives a reference to the sub-class, and the abstract Method HandleRequest () regulates the operation of the sub-class processing request.
specific Processor (concretehandler) role: when a specific processor receives a request, it can choose to dispose of the request or pass the request to the other person. As the specific processor holds references to the homes, the specific processor can access the homes if necessary.
Source
Abstract processor Role
Public abstract class Handler { /** * Holds successor to the object of responsibility */ protected Handler successor; /** * Signals the method of processing the request, although the schematic method is not passed in the parameters of the * but actually can pass in parameters, according to the specific needs to choose whether to pass the parameters */public abstract void HandleRequest (); /** * Value method * /public Handler getsuccessor () { return successor; } /** * Assignment method, set successor object of responsibility * /public void Setsuccessor (Handler successor) { this.successor = successor; } }
Specific processor roles
public class Concretehandler extends Handler { /** * Processing method, call this method to process the request */ @Override public Void HandleRequest () { /** * Determines if there is a successor to the object of responsibility * If there is, forward the request to the successor of the responsible object * If not, then process the request * /if (getsuccessor ()! = null) { System.out.println ("Leave Request"); Getsuccessor (). HandleRequest (); } else { System.out.println ("Processing request"); } }}
Client class
public class Client {public static void Main (string[] args) { //assemble responsibility chain Handler handler1 = new Concretehandl ER (); Handler handler2 = new Concretehandler (); Handler1.setsuccessor (handler2); Submit Request Handler1.handlerequest (); }}
As you can see, the client creates two processor objects and specifies that the first handler object is the second handler object, and the second handler object does not have a next one. The client then passes the request to the first handler object.
Because the delivery logic of this example is very simple: as long as there is a local, it is passed to the treatment of the under, if not the following, self-treatment. Therefore, after the first handler object receives the request, it passes the request to the second handler object. Because the second handler object does not have a next-of-a-person, it processes the request. The activity timing diagram is shown below.
Usage Scenarios
To consider such a function: to apply for the management of meal expenses.
Many companies are such benefits, that is, the project team or department can apply to the company for some meal expenses, to organize the project team members or members of the Department for dinner.
The general process of applying for a meal fee is generally: the applicant first fill out the application form, and then handed over to the leadership for approval, if the application approved, the leadership will inform the applicant approval, and then the applicant to finance the cost, if not approved, the leadership will inform the applicant approval failed, this matter also forget this.
Different levels of leadership, the amount of approval is not the same, for example, the project manager can only approve the application within 500 yuan, the department manager can approve the application within 1000 yuan, and the general manager can review any amount of applications.
That is, when a person makes a request for a meal fee application, the request is processed by a leader of the project manager, the department manager, and the general manager, but the person who made the application does not know who will ultimately handle his request, and the general applicant submits his application to the project manager, Perhaps finally, the general manager will deal with his request.
You can use the responsibility chain model to do this: when a request for a meal fee application is made, the request is delivered to the manager of the project manager,-〉 , manager-〉, a leader who does not know who will handle his request, Each leader will decide whether to handle the request or submit the request to a higher-level leader, depending on the scope of his or her responsibilities, and the delivery is over as long as the leader has dealt with it.
It is necessary to separate the processing of each leader into separate responsibilities, and then provide them with a common, abstract parent responsibility object, so that the responsibility chain can be combined dynamically in the client to achieve different functional requirements.
Source
Abstract processor Role Class
Public abstract class Handler { /** * holds the next object processing request */ protected Handler successor = NULL; /** * Value method * /public Handler getsuccessor () { return successor; } /** * Set the next object to process the request * /public void Setsuccessor (Handler successor) { this.successor = successor; * /** * for processing meal fee * @param user Applicant * @param the amount of money requested by fee * @return specific notice of success or failure * /Public abstract string Handlefeerequest (string user, double fee);}
Specific processor roles
public class Projectmanager extends Handler { @Override public string handlefeerequest (string user, double fee) { String str = ""; Project manager permissions are relatively small, only within 500 if (fee <) { //In order to test, simple point, only agree to Zhang San request if ("Zhang San". Equals (user)) { str = "Success: The project manager agrees" "+ user +" "The cost of the meal, the amount is" + fee + "Yuan; } else { //Everyone else does not agree with str = "Failure: The project manager does not agree with" + user + "" Dinner fee, the amount is "+ fee +" Yuan "; } } else { //More than 500, continue to pass to higher-level people handling if (getsuccessor () = null) { return getsuccessor (). Handlefeerequest (user, fee); } } return str; }}
public class Deptmanager extends Handler { @Override public string handlefeerequest (string user, double fee) {
string str = ""; Department manager's permission can only be within 1000 if (fee <) { //For testing, simple point, only agree to Zhang San request if ("Zhang San". Equals (user) { str = ") Success: The department manager agrees with the "+ User +" "Dinner fee, the amount is" + fee + "Yuan"; } else { //Everyone else does not agree with str = "Failure: Department manager does not agree with" + user + "" "The cost of the dinner, the amount is" + fee + "Yuan"; } } else { //More than 1000, continue to pass to higher-level people handling if (getsuccessor () = null) { return getsuccessor (). Handlefeerequest (user, fee); } } return str; }}
public class Generalmanager extends Handler { @Override public string handlefeerequest (string user, double fee) { String str = ""; The general manager's authority is very large, as long as the request to here, he can handle if (fee >=) { //In order to test, simple point, only agree to Zhang San request if ("Zhang San". Equals (user) { str = "SUCCESS: The general manager agrees" "+ user +" "The cost of the meal, the amount is" + fee + "Yuan"; } else { //Everyone else does not agree with str = "Failure: The general manager does not agree" + user + "" The meal fee, the amount is "+ fee +" Yuan "; } } else { //If there are subsequent processing objects, continue to pass if (getsuccessor ()! = null) { return getsuccessor (). Handlefeerequest (user, fee); } } return str; }}
Client class
public class Client {public static void main (string[] args) {//First to assemble the responsibility chain Handler h1 = new Generalmanager ( ); Handler h2 = new Deptmanager (); Handler h3 = new Projectmanager (); H3.setsuccessor (H2); H2.setsuccessor (H1); Start Test String test1 = H3.handlefeerequest ("Zhang San", 300); System.out.println ("test1 =" + test1); String test2 = h3.handlefeerequest ("John Doe", 300); System.out.println ("test2 =" + test2); System.out.println ("---------------------------------------"); String test3 = H3.handlefeerequest ("Zhang San", 700); System.out.println ("test3 =" + test3); String test4 = h3.handlefeerequest ("John Doe", 700); System.out.println ("test4 =" + test4); System.out.println ("---------------------------------------"); String test5 = H3.handlefeerequest ("Zhang San", 1500); System.out.println ("test5 =" + test5); String Test6 = h3.handlefeerequest ("John Doe", 1500); System.out.println ("Test6 =" + Test6); }}
The results of the operation are as follows:
Pure and impure chain of Duty mode
A pure chain of responsibility requires a specific handler object to choose only one of two behaviors: one is to take responsibility, but to push the responsibility to the next. A situation in which a specific processor object is not allowed to transmit responsibility after taking part of the responsibility.
In a pure chain of responsibility, a request must be received by a handler object, and in an impure chain of responsibility, a request can eventually not be received by any of the receiving end objects.
The actual example of the pure responsibility chain model is difficult to find, and the examples we see are the implementation of the impure responsibility chain model. Some people think that the impure chain of responsibility is not the responsibility chain at all, which may make sense. But in a real system, a pure chain of responsibility is hard to find. If the adherence to the chain of responsibility is not the responsibility chain model, then the chain of responsibility model will not have much significance.
Design pattern--8, responsibility chain mode