Latest web development tutorials

Chain of responsibility pattern

As the name suggests, Chain of Responsibility pattern (Chain of Responsibility Pattern) for the request to create a chain of a receiver object. This type of pattern given to the request, the sender and recipient of the request decoupling. This type of design patterns belong behavioral patterns.

In this mode, each recipient usually contains a reference to another recipient. If an object can not process the request, then it will the same request to the next recipient, and so on.

Introduction

Intent: Avoid requesting the sender and receiver are coupled together so that multiple objects are likely to receive requests, these objects will be connected into a chain, and pass the request along the chain until an object handles it so far.

Processor Processor duty chain responsible for handling requests, customers only need to send the request to the chain of responsibility can, need not concern the request transfer processing details and requests, so the chain of responsibility and the request of the sender'srequest: the main solution decoupled.

When to use: when dealing with a lot of road to filter messages.

How to fix: interception classes implement a unified interface.

The key code: Handler inside the polymerization itself, in HanleRequest where appropriate to determine whether, if the conditions are passed down not up, before whom passed into the set.

Application examples: 1, The Dream of Red Mansions "Drumming pass to spend."2, JS events bubbling. 3, JAVA WEB Encoding in the Apache Tomcat for processing, Struts2 interceptor, jsp servlet's Filter.

Advantages: 1, reduce the coupling.It requests the sender and receiver decoupling. 2, simplified object. So that objects do not need to know the structure of the chain. 3, to enhance the flexibility of the object assigned responsibilities. By changing the chain members or mobilize their order, allowing dynamic add or delete liability. 4, add a new request handler class is very convenient.

Disadvantages: 1, can not guarantee that the request must be received.2, the system performance will be affected, but less convenient during debugging code may cause the cycle call. 3, may not be readily observable characteristics runtime hinder debugging.

Usage scenarios: 1, more than one object can handle the same request, specifically which object to process the request is automatically determined by the run time.2, without explicitly specify the recipient to submit a request to a plurality of objects. 3, a set of objects can be dynamically assigned to process the request.

Note: encountered in many applications in JAVA WEB.

achieve

We create an abstract classAbstractLogger,with detailed logging level. We then create three types of recorders are extendedAbstractLogger.Each level logger messages whether their own level, if it is then printed out accordingly, otherwise it will not print the message to the next and a recorder.

Chain of Responsibility pattern UML diagram

step 1

Create abstract class record.

AbstractLogger.java

public abstract class AbstractLogger {
   public static int INFO = 1;
   public static int DEBUG = 2;
   public static int ERROR = 3;

   protected int level;

   // The chain of responsibility in the next element protected AbstractLogger nextLogger;

   public void setNextLogger (AbstractLogger nextLogger) {
      this.nextLogger = nextLogger;
   }

   public void logMessage (int level, String message) {
      if (this.level <= level) {
         write (message);
      }
      if (nextLogger! = null) {
         nextLogger.logMessage (level, message);
      }
   }

   abstract protected void write (String message);
	
}

Step 2

Create entity classes that extend the record class.

ConsoleLogger.java

public class ConsoleLogger extends AbstractLogger {

   public ConsoleLogger (int level) {
      this.level = level;
   }

   @Override
   protected void write (String message) {		
      System.out.println ( "Standard Console :: Logger:" + message);
   }
}

ErrorLogger.java

public class ErrorLogger extends AbstractLogger {

   public ErrorLogger (int level) {
      this.level = level;
   }

   @Override
   protected void write (String message) {		
      System.out.println ( "Error Console :: Logger:" + message);
   }
}

FileLogger.java

public class FileLogger extends AbstractLogger {

   public FileLogger (int level) {
      this.level = level;
   }

   @Override
   protected void write (String message) {		
      System.out.println ( "File :: Logger:" + message);
   }
}

Step 3

Create different types of recorders. Give them different levels of error, and setting a record in each of the recorder. Each logger recorder next representative is part of the chain.

ChainPatternDemo.java

public class ChainPatternDemo {
	
   private static AbstractLogger getChainOfLoggers () {

      AbstractLogger errorLogger = new ErrorLogger (AbstractLogger.ERROR);
      AbstractLogger fileLogger = new FileLogger (AbstractLogger.DEBUG);
      AbstractLogger consoleLogger = new ConsoleLogger (AbstractLogger.INFO);

      errorLogger.setNextLogger (fileLogger);
      fileLogger.setNextLogger (consoleLogger);

      return errorLogger;	
   }

   public static void main (String [] args) {
      AbstractLogger loggerChain = getChainOfLoggers ();

      loggerChain.logMessage (AbstractLogger.INFO, 
         "This is an information.");

      loggerChain.logMessage (AbstractLogger.DEBUG, 
         "This is an debug level information.");

      loggerChain.logMessage (AbstractLogger.ERROR, 
         "This is an error information.");
   }
}

Step 4

Verify output.

Standard Console :: Logger: This is an information.
File :: Logger: This is an debug level information.
Standard Console :: Logger: This is an 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.