As the name implies, the chain of responsibility pattern (Chain of Responsibility Pattern) creates a chain of recipient objects for the request. This pattern gives the type of request and decouples the sender and receiver of the request. This type of design pattern belongs to behavioral pattern.
In this pattern, each recipient usually contains a reference to another receiver. If an object cannot process the request, it passes the same request to the next recipient, and so on. 意图: Avoid coupling the request sender and receiver, making it possible for multiple objects to receive the request, connect the objects into a chain, and pass the request along the chain until an object processes it. 主要解决: The processor on the responsibility chain is responsible for processing the request, and the customer only needs to send the request to the responsibility chain, without paying attention to the processing details and delivery of the request, so the responsibility chain decouples the sender of the request from the processor of the request. 何时使用: Filter a lot of messages when processing messages. 如何解决: All intercepted classes implement a unified interface. 关键代码: Handler aggregates itself, determines whether it is appropriate in HandlerRequest, passes it down if the condition is not met, and goes in before set to whom it is passed. 应用实例: 1. “beating drums and spreading flowers” in A Dream of Red Mansions. 2. Event bubbling in JS. 3. The processing of Encoding by Apache Tomcat in JAVA WEB, the interceptor of Struts2, the Filter of jsp servlet. 优点: 1. Reduce the degree of coupling. It decouples the sender and receiver of the request. 2. The object is simplified. So that the object does not need to know the structure of the chain. 3. Enhance the flexibility of assigning responsibilities to objects. Allow the dynamic addition or removal of responsibilities by changing the members of the chain or transferring their order. 4. It is convenient to add a new request processing class. 缺点: There is no guarantee that the request will be received. 2. The performance of the system will be affected to a certain extent, and it is not convenient to debug the code, which may cause circular calls. 3. It may not be easy to observe the characteristics of the runtime, which hinders debugging. 使用场景: 1. Multiple objects can handle the same request, and which object can handle the request is automatically determined by the run time. 2. Submit a request to one of multiple objects without explicitly specifying the recipient. 3. A set of objects can be dynamically specified to handle the request. 注意事项: Encountered a lot of applications in JAVA WEB. We create abstract classes AbstractLogger With a detailed logging level Then we create three types of loggers, all of which extend the AbstractLogger . Whether the level of each logger message belongs to its own level, and if so, it will be printed accordingly, otherwise the message will not be printed and the message will be passed to the next logger. Create an abstract logger class. Create an entity class that extends the logger class. Create different types of loggers. Give them different error levels and set the next logger in each logger. The next recorder in each logger represents part of the chain. Execute the program and output the result: 6.16.1. Introduction ¶
6.16.2. Realize ¶
6.16.3. Step 1 ¶
AbstractLogger.java ¶
publicabstractclassAbstractLogger{publicstaticintINFO=1;publicstaticintDEBUG=2;publicstaticintERROR=3;protectedintlevel;//责任链中的下一个元素protectedAbstractLoggernextLogger;publicvoidsetNextLogger(AbstractLoggernextLogger){this.nextLogger=nextLogger;}publicvoidlogMessage(intlevel,Stringmessage){if(this.level<=level){write(message);}if(nextLogger!=null){nextLogger.logMessage(level,message);}}abstractprotectedvoidwrite(Stringmessage);}
6.16.4. Step 2 ¶
ConsoleLogger.java ¶
publicclassConsoleLoggerextendsAbstractLogger{publicConsoleLogger(intlevel){this.level=level;}@Overrideprotectedvoidwrite(Stringmessage){System.out.println("Standard
Console::Logger:"+message);}}
ErrorLogger.java ¶
publicclassErrorLoggerextendsAbstractLogger{publicErrorLogger(intlevel){this.level=level;}@Overrideprotectedvoidwrite(Stringmessage){System.out.println("Error
Console::Logger:"+message);}}
FileLogger.java ¶
publicclassFileLoggerextendsAbstractLogger{publicFileLogger(intlevel){this.level=level;}@Overrideprotectedvoidwrite(Stringmessage){System.out.println("File::Logger:"+message);}}
6.16.5. Step 3 ¶
ChainPatternDemo.java ¶
publicclassChainPatternDemo{privatestaticAbstractLoggergetChainOfLoggers(){AbstractLoggererrorLogger=newErrorLogger(AbstractLogger.ERROR);AbstractLoggerfileLogger=newFileLogger(AbstractLogger.DEBUG);AbstractLoggerconsoleLogger=newConsoleLogger(AbstractLogger.INFO);errorLogger.setNextLogger(fileLogger);fileLogger.setNextLogger(consoleLogger);returnerrorLogger;}publicstaticvoidmain(String[]args){AbstractLoggerloggerChain=getChainOfLoggers();loggerChain.logMessage(AbstractLogger.INFO,"This
is an information.");loggerChain.logMessage(AbstractLogger.DEBUG,"This
is a debug level
information.");loggerChain.logMessage(AbstractLogger.ERROR,"This is an
error information.");}}
6.16.6. Step 4 ¶
Standard Console::Logger: This is an information.
File::Logger: This is a debug level information.
Standard Console::Logger: This is a debug level information.
Error Console::Logger: This is an error information.
File::Logger: This is an error information.
Standard Console::Logger: This is an error information.