I. Introduction of responsibility chain model

Iterator Pattern is one of the behavioral design patterns. The common chain in life is made up of circular rectangular iron rings. With a chain structure, each node can be taken apart and reconnected, so the chain structure also has great flexibility.

Would such a structure used in programming, to each node as an object, each object has a different processing logic, will be issued a request from the head end of the chain, along the path of the chain to each node object, until we have some objects to deal with this request, we will be such a pattern called the chain of responsibility pattern.

2. Definition of responsibility chain model

This avoids coupling between the sender and receiver of the request by giving multiple objects the opportunity to process the request. Connect the objects into a chain and pass the request along the chain until an object handles it.

Usage scenarios for the chain of responsibility pattern

  • Multiple objects can handle the same request, but which object handles it is dynamically determined at run time.

  • Submit a request to one of multiple objects without specifying the request handler.

  • You need to dynamically specify a set of objects to handle requests.

Responsibility chain model UML class diagram


Role Introduction:

  • Abstract Handler role: Defines an interface to handle requests. If necessary, the interface can define a method to set and return a reference to the next parent. This role is typically implemented by a Java abstract class or Java interface. The Handler class aggregation in the figure above gives a reference to a specific subclass’s next parent, and the abstract method handleRequest() specifies how subclasses handle requests.

  • The ConcreteHandler role: When a ConcreteHandler receives a request, it can choose to either process it or pass it on to the next provider. Because the concrete handler holds a reference to the next home, the concrete handler can access the next home if needed.

4. Cases of realization of responsibility chain mode

I think that’s a good example. We need to reimburse expenses for various reasons in the company. First of all, we need to ask our superior leader for approval. If the reimbursement amount is within the scope of authority of the leader, the approval will be approved; otherwise, the leader will ask his or her superior for approval, and so on.

1. Abstract leadership classes

public abstract class Leader {
  / * ** Superior handler* /
  protected Leader nextHandler;
 / * ** Process reimbursement requests * @paramThe amount of reimbursement money can approve* /  public final void handleRequest(int money){  System.out.println(getLeader());  if(money <=limit()){  handle(money);  }else{  System.out.println("Insufficient reimbursement amount, submit to the leader.");  if(null! = nextHandler){ nextHandler.handleRequest(money);  }  }  }  / * ** Limit permission that can be approved by itself * @returnlines* /  public abstract int limit(a);  / * ** Handle billing behavior * @paramMoney Specific amount* /  public abstract void handle(int money);  / * ** Get handler * @returnhandler* /  public abstract String getLeader(a); } Copy the code

The leadership of this abstract class only did two things, one is the abstract interface defines two methods to determine the behavior and the nature of a leader should have, 2 it is to declare a processing method of reimbursement requests to determine whether the current leadership has the ability to deal with reimbursement requests, if don’t have the permission, will forward the request to the superior leadership.

2. Implementation classes for each leadership class

Group leader (Quota: 1000) :

public class GroupLeader extends Leader{
  @Override
  public int limit(a) {
    return 1000;
  }
 @Override  public void handle(int money) {  System.out.println("Group leader approved reimbursement"+ money +"Yuan");  }  @Override  public String getLeader(a) {  return "Currently the group leader";  } } Copy the code

Supervisor (Limit 5000) :

public class Director extends Leader{
  @Override
  public int limit(a) {
    return 5000;
  }
 @Override  public void handle(int money) {  System.out.println("Supervisor approves reimbursement."+ money +"Yuan");  }  @Override  public String getLeader(a) {  return "Currently in charge";  } } Copy the code

Manager (Limit 10000) :

public class Manager extends Leader{
  @Override
  public int limit(a) {
    return 10000;
  }
 @Override  public void handle(int money) {  System.out.println("Manager approves reimbursement"+ money +"Yuan");  }  @Override  public String getLeader(a) {  return "Currently the manager";  } } Copy the code

Boss (quota…) :

public class Boss extends Leader{
  @Override
  public int limit(a) {
    return Integer.MAX_VALUE;
  }
 @Override  public void handle(int money) {  System.out.println("Boss approves reimbursement"+ money +"Yuan");  }  @Override  public String getLeader(a) {  return "Currently the boss";  } } Copy the code

3. Initiate an application

public class Client {
  public static void main(String[] args) {
    // Construct each leadership object
    GroupLeader groupLeader = new GroupLeader();
    Director director = new Director();
 Manager manager = new Manager();  Boss boss = new Boss();  // Set the superior handler object  groupLeader.nextHandler = director;  director.nextHandler = manager;  manager.nextHandler = boss;  // initiate a reimbursement request  groupLeader.handleRequest(8000);  } } Copy the code

4, the results

Currently the group leaderThe amount of reimbursement is insufficient, submit to the leaderCurrently in chargeThe amount of reimbursement is insufficient, submit to the leaderCurrently the managerThe manager approved the reimbursement8000yuanCopy the code

The chain of responsibility pattern is very flexible. Requests can be initiated from any node in the chain of responsibility, and internal delivery rules can be changed. If the supervisor is not there, we can go directly from the group leader to the manager.

There are two actions for a handler object in the chain of responsibility. The first is to process the request and the second is to pass the request to the next node. It is not allowed for a handler object to process the request and then pass the request to the previous node.

For a chain of responsibility, a request ultimately has only two possibilities. One is processed by a processing object, the other is not processed by all objects, for the former case we call the pure chain of responsibility mode, the latter is the impure chain of responsibility. In practice it is mostly impure chain of responsibility.

Five, Android source responsibility chain mode

View event distribution processing

A recursive call to a ViewGroup event post is similar to a chain of responsibilities. Once it finds the responsible person, the responsible person will hold and consume the event, which is reflected in the setting of the return value of the View’s onTouchEvent method. If false is returned, it means that the current View is not the responsible person for the event. Will not hold it; If true is returned, the View holds the event and does not pass it out again.

Android View tree structure:

The Activity — – > > PhoneWindow – > > decorView – > > ViewGroup > View

After pressing a button on a page, the first object that the event passes to is the Activity, and then passes down, In the process of event transmission, we use dispatchTouchEvent, onInterceptTouchEvent and onTouchEvent to handle the event request.

  • dispatchTouchEvent

    Event issued by the

    Views and viewGroups have methods

  • onInterceptTouchEvent

    Intercept the sent event and hand it to your OnTouchEvent handler

    ViewGroup methods

  • onTouchEvent

    Events reported

    Views and viewGroups have methods

Six, summarized

advantages

  1. Reduced coupling: the client does not need to know which handler is handling the request, and the handler does not need to know the transfer relationship between the handlers, which is flexibly organized and allocated by the system.
  2. Good extensibility: Adding handler implementations is as simple as rewriting the way the request business logic is handled.

disadvantages

  1. Requests are sent from the header until a handler responds, which can affect system performance when the chain of responsibilities is long.
  2. Request recursion, debugging troubleshooting is more troublesome.

For a handler object in the responsibility chain, it has only two behaviors, one is to process the request, and the other is to forward the request to the next node. It is not allowed for a handler object to process the request and then forward the request to the upper node.

A request for a chain of responsibility in the end only two cases, one is processing by an object, the other is a handle to its all objects are not, for the former a situation in which we call the chain of responsibility is the responsibility of the pure chain, for the latter case we call not pure chain of responsibility, in practice, we can see the chain of responsibility pattern mostly not pure chain of responsibility.

This article is formatted using MDNICE