Design Patterns (xv) Chain of Responsibility Chain of Responsibility

Chain of Responsibility defined
Chain of Responsibility (CoR) is attempting to process a request by a series of request classes (classes), a loose coupling between these classes, the only common denominator between them is transmitted request. That is to a request, a first process category, if not treated, it is transmitted to the class B treatment, if not treated, it is passed to the class C treated, so as a chain (chain) as passed on.

How to use?
Although this section is how to use the CoR, but also a demonstration of what is CoR.

There is a Handler Interface:

public interface Handler{
  public void handleRequest();
}

This is the case of a processing request, if there are multiple request, such as a print request or request help request format:

The first solution is conceivable: a plurality of requests to increase in the interface:
public interface Handler {
  public void handleHelp ();
  void handlePrint public ();
  public void handleFormat ();

}

It was a particular implementation of the interface Handler Code:
public class ConcreteHandler the implements Handler {
  Private Handler by successor;

  public ConcreteHandler(Handler successor){
  this.successor=successor;
}

  void handleHelp public () {
    // code specific processing request Help
    ...
  }

  void handlePrint public () {
    // If the process is to transfer print the Print
    successor.handlePrint ();
  }
  public void handleFormat () {
    // if it is Format turn to process the format
    successor.handleFormat ();
  }

}
There are three such specific implementation class, description of processing help, as well as handling the processing Print Format This is probably our most popular programming ideas.

Although the idea is simple, but there is an extension problem, if we need to add a request to the type of request, you need to modify the interface and each of its realization.

The second program: Each request will be turned into one interface, we have the following code:

public interface HelpHandler{
  public void handleHelp();
}

public interface PrintHandler{
  public void handlePrint();
}

public interface FormatHandler{
  public void handleFormat();
}

public class ConcreteHandler
  implements HelpHandler,PrintHandler,FormatHandlet{
  private HelpHandler helpSuccessor;
  private PrintHandler printSuccessor;
  private FormatHandler formatSuccessor;

  public ConcreteHandler(HelpHandler helpSuccessor,PrintHandler printSuccessor,FormatHandler             formatSuccessor)
  {
    this.helpSuccessor=helpSuccessor;
    this.printSuccessor=printSuccessor;
    this.formatSuccessor=formatSuccessor;
  }

  public void handleHelp(){
    .......
  }

  public void handlePrint(){this.printSuccessor=printSuccessor;}

  public void handleFormat(){this.formatSuccessor=formatSuccessor;}

}

This approach in adding new request request under the circumstances, but to save the amount of modification of the interface, interface ConcreteHandler also need to modify. And the code is clearly not simple beauty.

Solution 3: Using only one parameter Handler interface methods:
public interface Handler {
  public void the handleRequest (Request String);
}
then Handler codes are as follows:
public class ConcreteHandler the implements Handler {
  Private Handler by successor;

  public ConcreteHandler(Handler successor){
    this.successor=successor;
  }

  void the handleRequest public (Request String) {
    IF (request.equals ( "Help")) {
      // This is the code for specific processing of Help
    } the else
      // passed to the next
      successor.handle (request);

    }
  }

}

Here we assume that request is of type String, if not how to do? Of course, we can create a special class Request

Last Solution: Interface Handler code is as follows:
public interface Handler {
  public void the handleRequest (Request Request);
}
defined Request class:
public class Request {
  Private String type;

  public Request (String type) {type = this.type;}

  public String getType(){return type;}

  void Execute public () {
    // Request Action Code true specific
  }
}
Then Handler codes are as follows:
public class ConcreteHandler the implements Handler {
  Private Handler by successor;

  public ConcreteHandler(Handler successor){
    this.successor=successor;
  }

  void the handleRequest public (the Request Request) {
    IF (Request the instanceof the HelpRequest) {
      // This is the code for specific processing of Help
    } the else IF (Request the instanceof PrintRequst) {
      request.execute ();
    } the else
      // passed to the next
      successor.handle (request);

    }
  }

}

This solution is the CoR, on a chain, there is a corresponding duty class, so called Chain of Responsibility .

The CoR advantage:
because they can not predict a request from the outside world (clients) what type belonging to each category if it can not meet the request to give up as long as you can handle.

The disadvantage is low efficiency, because the completion of a request may be possible to traverse the last to complete, of course, you can also use the concept of a tree optimization. In Java AWT1.0, for processing the mouse button thing is to use the CoR, to later Java.1.1, instead of just using the Observer CoR

Poor scalability, because in the CoR, there must be a unified interface Handler. Limitations here.

And Command mode differences:

Command mode requires prior consultations call relationship of client and server, such as the representative start 2 represents move the like, which are encapsulated in the request, the server again reaches the decomposition.

This mode there is no need CoR prior agreement, the server may be used to guess CoR mode requested by the client, a guess test.

Reproduced in: https: //www.cnblogs.com/moiyer/archive/2011/08/08/2316175.html

Guess you like

Origin blog.csdn.net/weixin_34413357/article/details/94693159