java design pattern: responsibility chain pattern (enterprise case)

There are 23 java design patterns in total, which are mainly divided into three categories:

1: Creation mode

Factory method pattern, abstract factory pattern, singleton pattern, creator pattern, prototype pattern.

2: Structural mode

Adapter mode, decorator mode, agent mode, appearance mode, bridge mode, combination mode and sharing element mode.

3: Behavior pattern

Strategy mode, template method mode, observer mode, iteration sub mode, responsibility chain mode, command mode, memo mode, visitor mode, mediator mode, interpreter mode.

Today we mainly talk about the responsibility chain mode in the behavior mode:
 

The model of responsibility chain in vernacular

What is the mode of responsibility chain: the mode of responsibility chain, so the name "thinking" is a chain, which consists of one chain and the next. The requester only needs to initiate the request, but does not need to know the specific implementation. The purpose is to solve the decoupling between the requester and the implementer.

The responsibility chain is generally composed of multiple implementations. When a request is received, the first implementation in the responsibility chain will judge whether it can be processed. If it can't be processed, it will be passed to the next processing, so it will be executed in order. Of course, the next one is who we specify when we define it. The implementation order is specified when we create it.

Benefits of the chain of responsibility:

1. Decouple request and implementation to facilitate management and maintenance.

2. The specific implementation does not need to know the internal structure of the responsibility chain, but only needs to maintain its own implementation, which reduces the maintenance difficulty

3. You can modify the execution order of the internal chain

4. It is simple and convenient to add.

Disadvantages of the responsibility chain:

1. Because we only care about our own internal implementation and do not care about the internal structure of the chain, development and debugging will be more troublesome. Because you have no idea which implementation he will call.

2. Increase the resource consumption of the system. Because of the chain call, it may be judged many times, because each implementation will judge whether it can process the request, and if it can't, it will call the next one, which increases the system overhead

3. There is no guarantee that the request will be digested. Because of its special characteristics, whether it can be processed will be judged before processing. If each chain cannot be processed, the request cannot be digested.

Application scenario of responsibility chain: filter filter in java, various permission control.

Illustration:

Responsibility chain model

 

Through the above figure, we briefly analyze the principle of a responsibility chain and the implementation process. Why can I decouple the caller and the implementation?

The appeal flowchart has two important roles,

First: our parent class abstract method, which is temporarily called abstractHandle. Our abstractHandle function is to provide the abstract function interface and the method to set the next implementation chain.

Second: our implementation factory, temporarily called chainFactory, our chainFactory is used to manage our responsibility chain. It is responsible for creating and managing the calling order of each responsibility chain, that is, the execution order and the creation are completed here.

In addition to the two roles of appeal, we have the rest of the specific implementation. Each implementation is only responsible for the part that needs to be implemented, and the next implementation is called for the part that does not meet the requirements.

The above briefly introduces each role in our responsibility chain. Then we will explain the responsibility chain pattern according to a simple java example and our figure above. You can also refer to our filter in Java.

 

Case introduction: we use the responsibility chain to design a simple java company leave approval program. If the days of leave are within the acceptable range, we will handle it by ourselves. If we can't handle it, we won't give it to the next implementation. Specifically, we don't care about that.

Key roles:

1. The department head shall accept the leave request within three days.

2. The personnel manager shall accept the leave request with a duration of four to eight days.

3. The project manager shall deal with the leave time longer than eight days. If it is not longer than 12 days, it is allowed. Otherwise, it is rejected.

By the way. If it is a traditional processing scheme, we need to judge the length of leave, use if else if or switch to make conditional judgment and call different methods, but use the responsibility chain mode to avoid multiple if and switch. (just remember that the responsibility chain can solve multiple if and switch)

Well, let's start coding:

1. First, we define our abstractHandle class:

/**
 * Audit class
 *
 * @author Li City
 */
@Data
@SuppressWarnings("unused")
@AllArgsConstructor
@NoArgsConstructor
public abstract class BaseAudit {


    /**
     * Leave processing object
     */
    protected BaseAudit audit;


    /**
     * Leave processing
     */
    abstract boolean vacateAudit(int number) throws Exception;

    /**
     * Start next processing
     */
    boolean nextAudit(int number) throws Exception {
        return audit.vacateAudit(number);
    }

}

Our abstractHandle has only two methods and one member property, which are used to process leave, and call the next implementation to process leave and save the member property of the next implementation.

2. With the member attribute, we start to create a specific implementation:

Department head

/**
 * Reviewed by department head
 *
 * @author Li City
 */
public class DepartmentManagerAudit extends BaseAudit {


    @Override
    public boolean vacateAudit(int number) throws Exception {
        if (number > 3) {
            return nextAudit(number);
        }
        System.out.println("\t\n The department head begins to deal with leave.");
        System.out.println("I'm the head of the Department. I agree");
        return true;
    }
}

Personnel manager

/**
 * Reviewed by HR supervisor
 *
 * @author Li City
 **/
public class PersonnelManagerAudit extends BaseAudit {


    @Override
    public boolean vacateAudit(int number) throws Exception {
        if (number > 8) {
            return nextAudit(number);
        }
        System.out.println("\t\n The Personnel Supervisor starts to deal with leave.");
        System.out.println("I'm the head of personnel. I agree");
        return true;
    }
}

project manager

/**
 * project manager
 *
 * @author Li City
 **/
public class ProjectManagerAudit extends BaseAudit {

    @Override
    public boolean vacateAudit(int number) throws Exception {
        System.out.println("\t\n The project manager starts to deal with leave.");
        if (number > 12) {
            throw new IllegalAccessException("The project is tense, and the leave days cannot be more than 3 days, so it will not be approved.");
        }
        System.out.println("I'm the project manager, I agree.");
        return true;
    }
}

3. With our specific implementation, we need a factory to create and manage our responsibility chain for us.

/**
 * Audit factory
 *
 * @author Administrator
 **/
public class AuditFactory {

    /**
     * Get the first reviewer
     *
     * @return To examine
     */
    public DepartmentManagerAudit getBaseAudit() {
        //Department head
        DepartmentManagerAudit departmentManagerAudit = new DepartmentManagerAudit();
        //Personnel manager
        PersonnelManagerAudit personnelManagerAudit = new PersonnelManagerAudit();
        departmentManagerAudit.setAudit(personnelManagerAudit);

        //project manager
        ProjectManagerAudit projectManagerAudit = new ProjectManagerAudit();
        personnelManagerAudit.setAudit(projectManagerAudit);
        return departmentManagerAudit;
    }
}

Our factory can clearly see that we have created three implementations, namely, department director, personnel manager and project manager, which correspond to department manager audit, personal manager audit and project manager audit respectively, and specify the order of responsibility chain execution, namely, department director, personnel manager and project manager.

4.ok, let's design our request caller

/**
 * Startup class
 *
 * @author Li City
 */
public class App {


    public static void main(String[] args) {
        AuditFactory auditFactory = new AuditFactory();
        DepartmentManagerAudit baseAudit = auditFactory.getBaseAudit();
        Scanner scanner = new Scanner(System.in);
        for (int i = 0; i < 10; i++) {
            System.out.print("\t\n Hello, please input your leave days:");
            if (!scanner.hasNextInt()) {
                System.out.println("Please enter legal leave days");
                continue;
            }
            int number = scanner.nextInt();
            System.out.println("The application for leave has been submitted.");
            try {
                if(baseAudit.vacateAudit(number)){
                    System.out.println("Congratulations on your success in asking for leave!");
                };

            } catch (Exception e) {
                System.out.println("Leave failed:" + e.getMessage());
                continue;
            }
        }
    }
}

ok, we can see that we get the examples of our abstract audit leave through the factory, then enter the request for leave, input the number of days, call our audit method to judge and determine the specific processing person, but in the whole process, the caller knows nothing, and does not know what to do, only knows that he submitted the leave request. In this way, the coupling between the caller and the applicant is well solved, and each role (Department Director, personnel director, project manager) only needs to maintain its own implementation mode, which is also convenient for maintenance. The same disadvantage is that if there is a problem, the bad process will end up as a black box as the factory. Let's reject our specific implementation completely

Code address: https://gitee.com/happy_bug/designMode/tree/master/src/main/java/com/likuncheng/responsibilitychain

 

In addition, I will bring the real case of enterprise level below, and only the key code can be posted here.

First of all, we will explain the requirements: requirements are a function of multi role and multi permission login,

It is multi role login. The login user only needs to tell me what role you are and the key login information. The caller does not know the implementation of each role at all.

The department key code is posted here: https://gitee.com/happy_bug/designMode/tree/master/src/main/java/com/likuncheng/responsibilitychain/enterprisecase

Published 27 original articles, won praise 13, visited 7376
Private letter follow

Tags: Java supervisor REST Attribute

Posted on Sun, 15 Mar 2020 01:01:41 -0400 by expostfacto