Android Design Patterns - Responsibility Chain Patterns

Posted by lathifmca on Sat, 18 May 2019 04:17:41 +0200

Preface

Android Design Patterns series articles, welcome attention, ongoing updates:

1. definition

A request is passed along a "chain" until a handler on the "chain" processes it.

2. introduction

  • Responsibility chain model belongs to behavioral model.
  • In multiple objects, each object holds a reference to the next object, which constitutes a chain structure.
  • A request passes through the head of the chain and down to each node in the chain until a node handles the request. This is the responsibility chain model.
  • The responsibility chain model is generally divided into the handler and the requester. The specific handler handles the requester's behavior separately.

3.UML class diagram

Role description:
  • Handler: An abstract class or interface that defines how requests are processed and holds a reference to the next Handler.
  • ConcreteHandler 1, ConcreteHandler 2 (Specific Processor): Implements abstract processing classes, processes requests, and forwards them to the next processor if they are not processed.
  • Client (Client): Where the responsibility chain pattern is to be used.

4. implementation

Take express delivery as an example, a single courier is only responsible for the express delivery of a certain area. If a certain express destination does not belong to the current area, it will be handled by the next courier until someone handles it.

4.1 Create an abstract Handler class that defines how requests are processed and holds a reference to the next Handler:

    public abstract class Postman {//Expressor abstract class
        protected Postman nextPostman;//Next courier

        public abstract void handleCourier(String address);//Delivery express
    }

4.2 Create concrete handler classes to implement methods in abstract handler classes:

    public class BeijingPostman extends Postman {//Beijing Express

        @Override
        public void handleCourier(String address) {
            if (address.equals("Beijing")) {//Delivery in Beijing
                System.out.println("Delivered to Beijing");
                return;
            } else {//Otherwise, it will be handed over to the next courier.
                nextPostman.handleCourier(address);
            }
        }
    }

    public class ShanghaiPostman extends Postman {//Shanghai Express

        @Override
        public void handleCourier(String address) {
            if (address.equals("Shanghai")) {
                System.out.println("Delivery to Shanghai");
                return;
            } else {
                nextPostman.handleCourier(address);
            }
        }
    }

    public class GuangzhouPostman extends Postman {//Guangzhou Express

        @Override
        public void handleCourier(String address) {
            if (address.equals("Guangzhou")) {
                System.out.println("Delivered to Guangzhou");
                return;
            } else {
                if (nextPostman != null)
                    nextPostman.handleCourier(address);
            }
        }
    }

4.3 Client Testing:

    public void test() {
        //Create different courier objects
        Postman beijingPostman = new BeijingPostman();
        Postman shanghaiPostman = new ShanghaiPostman();
        Postman guangzhouPostman = new GuangzhouPostman();

        //Create the next node
        beijingPostman.nextPostman=shanghaiPostman;
        shanghaiPostman.nextPostman=guangzhouPostman;

        //Processing express delivery in different areas starts with Beijing Express Delivery Clerk at the first node.
        System.out.println("There's a Shanghai Express that needs to be delivered.:");
        beijingPostman.handleCourier("Shanghai");
        System.out.println("There's a Guangzhou Express that needs to be dispatched.:");
        beijingPostman.handleCourier("Guangzhou");
        System.out.println("There's an American Express that needs to be delivered.:");
        beijingPostman.handleCourier("America");

    }

Output results:

There is a Shanghai Express to be dispatched:
Delivery to Shanghai
 There is a Guangzhou Express to be dispatched:
Delivered to Guangzhou
 There is an American Express that needs to be delivered:

4.4 Notes:

  • The above request is just a simple address string. If it is a complex request, it can be encapsulated as a separate object. Such as: ordinary express delivery and fresh express delivery, fresh express delivery also need express courier to do cold chain processing and so on.
  • Requests can actually start from any node in the chain of responsibility, that is, from Shanghai Express.
  • The order of nodes in the responsibility chain can also be adjusted, that is, the order of Beijing - > Guangzhou - > Shanghai can also be adjusted.
  • The chain of responsibility can also handle requests across certain nodes, such as Beijing - > Guangzhou and Shanghai.
  • For requests, there are only two results: one is that a node handles them, such as Shanghai Express and Guangzhou Express, which are called pure responsibility chain; the other is that all nodes do not handle them, such as American Express, which is called impure responsibility chain. What we see is basically a chain of impure responsibilities.

5. Application scenarios

  • When multiple objects process the same request, the runtime judgment is needed to decide which object to process.
  • A request is submitted to this group of objects when the specific handler is not clear.

6. advantages

  • Code decoupling, isolation between requester and processor.
  • Easy to expand, add new processors to the chain can add nodes.

7. disadvantages

  • If the responsibility chain is too long, or if the node judgment processing time on the chain is too long, the performance will be affected, especially when the recursive loop is in progress.
  • The request may not be processed after traversing the chain.

8. Source code analysis in Android

  • The event distribution mechanism in Android is similar to the responsibility chain model. As for the event distribution mechanism, we don't elaborate on it here, but take a pit first, and then we will discuss it in another article.
  • In addition, OKhttp also uses the responsibility chain model to handle requests. If you are interested, you can look at the source code of OKhttp. The source code of OKhttp will be analyzed later.

Topics: Android OkHttp