Love life, enjoy entertainment, focus on technology, welcome to the public Qger, we witness growth together!
What is the responsibility chain model?
Official explanation: Avoid coupling the sender of a request to their receiver by giving multiple objects a chance to handle the request.
Enables multiple objects to have the opportunity to process requests, thus avoiding the coupling between the sender and the recipient of the request.
- Popular explanation: An execution command may be handled by multiple objects, in order to avoid a more complex association between the sender and the receiving (processing) command, treating the objects as one node in a chain of responsibility and having the request command pass through the chain of responsibility, which have the opportunity to process the request.
Why use the responsibility chain model?
The sending command is decoupled from the receiving command, and if it is not packaged, it is possible for a command to correspond to an object that handles the command, so that the association between the sender and the receiving command becomes complex, forming a strong coupling relationship. This is not good for the expansion of the system. The command processing object is stitched into a chain of responsibility to handle the command, which makes the sender and the recipient weak association, reduces the coupling, and is easy to expand.
The links between the command-handling objects are implemented by Inheritors (successor), which makes the order of the nodes flexible and does not require a fixed order.
- The responsibility chain gives you more flexibility when assigning responsibilities in an object. You can add or change the responsibilities of handling a request by dynamically adding or modifying the chain at run time. You can use this mechanism in conjunction with the inheritance mechanism of static exception handling objects.
How do I use the responsibility chain model?
The UML diagram of the responsibility chain model is as follows:
Each component explains:
Client: The sender of the command.
Handler: Abstract command processor, which defines an abstract interface for processing commands, and a Handler as an inheritor (successor).
- Concretehandler: The specific command processor implements the method of handling the command and determines who inherits the next command when a command does not need to be handled by itself.
Scope of Use:
- Multiple objects can handle a single request
- When a relationship between a command sender and the recipient does not want to be explicitly specified, the command object wants to be sent to a set of command handlers and does not display the specified receiver
- An object that handles an instruction must be dynamically specified
Pure and not pure liability chain:
There is a saying that the command processing node of the pure chain of responsibility only needs to do: process the command and return, do not process the command and pass . That is, the command may be passed to the node that should be processed and the delivery is interrupted.
The command processing node for the impure chain of responsibility is this: processing the command and passing it, not processing it, and passing it. That is, the command is bound to pass the entire chain of responsibility, where all nodes are likely to respond to and process the command. There may be one node processing, or multiple nodes processing . The servlet filter uses this design structure.
Personally, there is no so-called pure and impure said, mainly to see what kind of implementation you need, ultimately, the chain of responsibility is simply to provide a command-handling packaging, so that the code is more tidy, the system more easily expand.
Application Examples:
Now we have such a requirement, I want to implement a text parsing function, file files as commands, different suffix format files need to be parsed with different parsers (recipients), then we can:
1, defines an abstract parser class, implements the public method, and declares the parsing file abstract method.
Public Abstract classParser {PrivateParser successor;protectedString Fomat; Public void Transfer(File file) {if(Getsuccessor ()! =NULL) {Getsuccessor (). Parse (file); }Else{System. out. println ("Unable to find the relevant processor to parse the text"); } } Public Abstract void Parse(file file);protectedBooleanCanparsefile(File file) {return(File! =NULL) && (File.getname (). EndsWith ( This. Fomat)); } Public void Setfomat(String Fomat) { This. Fomat = Fomat; } PublicParserGetsuccessor() {returnsuccessor; } Public void Setsuccessor(Parser successor) { This. successor = successor; }}
2, define the specific parser, when the file belongs to the scope of its own parsing, parsing, otherwise passed to the successor.
Public class TextParser extends Parser { Public TextParser(Parser successor) {Setfomat ("TXT"); Setsuccessor (successor); }@Override Public void Parse(File file) {if(Canparsefile (file)) {System.out.println (File.getname () +"text file parsing succeeded"); }Else{Super. Transfer (file); } }} Public class xmlparser extends Parser { Public Xmlparser() {Setfomat ("xml"); }@Override Public void Parse(File file) {if(Canparsefile (file)) {System.out.println (File.getname () +"XML file parsing succeeded"); }Else{Super. Transfer (file); } }}
3. Define the order of the parser in the chain of responsibility in the client. The brevity here is: Text->xml.
publicclass client { publicstaticvoidmain(String[] args) { new XmlParser(); new TextParser(xmlParser); textParser.parse(new File("test.xml")); }}
- Here can expand the place:1, can flexibly increase the parser 2, the initialization of the successor is not in the construction method and use setter Method 3, according to the requirements can be changed to a file to parse the function of multiple text format , such as the said "impure" responsibility chain, Specific details You can study it yourself.
Talking about design pattern: Responsibility chain mode (Chain of Responsibility)