Design Patterns of the Chain of Responsibility Pattern (ChainofResponsibility) Introducing the Chain of Responsibility Pattern Examples of the Chain of Responsibility Pattern Analysis of the Chain of Responsibility Pattern Applications of the Chain of Responsibility Pattern
The chain of responsibility model describes how to pass the buck, or to put it succinctly, kick the bucket haha. For example, sometimes, something goes wrong, we go to fix it, we find A, only to have A kick the can down the road and say it's none of my business, go to B and fix it, then we go to B, only to have B also say, it's none of my business, go to C. That's it, we get kicked around, that's the idea of the chain of responsibility model, until we find the right person to fix it, we get kicked around constantly to one and one person, just passing the buck. The above example, may be a bit pejorative, but in actual programming, there are sometimes situations where we do need to pass the buck,, for example, when we receive a request and the current program is temporarily unable to handle the request, so we need to give the request to someone else to handle. If you are a web developer, you should be familiar with this, when the server receives a request from the client, it will first parse the request, the action layer will not process the request, but will simply parse the request parameters and other information, and then forward the request specifically to the service to process according to the request content information. When a person is asked to do something, if he can do it himself, then he does it himself, if he can't do it himself, then he forwards it to another person who does the same, if he can do it himself, then he does it, if not, then he gives it to someone else 。。。。。。 This is the basic idea of the chain-of-responsibility model
Class diagram for instances
image.png
Support is an abstract class with a core method support in which if the current support can be solved, it will be solved, if not, it will be given to next to solve.
package ChainOfResponse; public abstract class Support { private String name; private Support next; public Support(String name) { this.name = name; } public Support setNext(Support next) { this.next = next; return next; } public final void support(Trouble trouble) { if(resolve(trouble)) { done(trouble); } else if (next != null) { next.support(trouble); } else { fail(trouble); } } public String toString() { // Display String return "[" + name + "]"; } protected abstract boolean resolve(Trouble trouble); protected void done(Trouble trouble) { System.out.println(trouble + " is resolved by " + this + "."); } protected void fail(Trouble trouble) { // unsolved System.out.println(trouble + " cannot be resolved."); } }
Then we implement a few specific support classes The NoSupport class is a class that never solves a problem
package ChainOfResponse; public class NoSupport extends Support { public NoSupport(String name) { super(name); } @Override protected boolean resolve(Trouble trouble) { return false; } }
LimitSupport class to solve problems within a specified range
package ChainOfResponse; public class LimitSupport extends Support { private int limit; public LimitSupport(String name, int limit) { super(name); this.limit = limit; } @Override protected boolean resolve(Trouble trouble) { if(trouble.getNumber() < limit) return true; return false; } }
OddSupport class, solve the problem of odd numbers
package ChainOfResponse; public class OddSupport extends Support { public OddSupport(String name) { super(name); } @Override protected boolean resolve(Trouble trouble) { if(trouble.getNumber() % 2 == 1) return true; return false; } }
package ChainOfResponse; public class SpecialSupport extends Support { private int number; public SpecialSupport(String name, int number) { super(name); this.number = number; } @Override protected boolean resolve(Trouble trouble) { if(trouble.getNumber() == number) return true; return false; } }
, Finally, implement a main class.
package ChainOfResponse; public class Main { public static void main(String[] args) { Support alice = new NoSupport("Alice"); Support bob = new LimitSupport("Bob", 100); Support charlie = new SpecialSupport("Charlie", 429); Support diana = new LimitSupport("Diana", 200); Support elmo = new OddSupport("Elmo"); Support fred = new LimitSupport("Fred", 300); alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred); for(int i=0;i<500;i+=33) { alice.support(new Trouble(i)); } } }
The Main class defines a chain of responsibility that connects several support objects together to form a chain of responsibility that then goes to work on the problem The results of the run are as follows.
image.png
First, there are several roles in the chain-of-responsibility model.
The class diagram for the chain-of-responsibility model is as follows.
image.png
In the windowing system, the chain of responsibility pattern is often used, especially the handling of events. Those who are familiar with javascript development may know that the events in the browser have a bubbling mechanism, that is, the events are propagated to the parent control, and if they can't handle themselves, they are propagated to the parent control to handle.