The of design patterns -- the combination of Java responsibility chain pattern and builder pattern

Posted by markusn00b on Sun, 28 Nov 2021 16:17:26 +0100

The previous chapter introduces the business scenarios and usage of the simple responsibility chain model. In actual code, it may be better to combine multiple modes.
The implementation of the service in the previous article is very cumbersome, and the next must be specified. These cannot handle the business gracefully in the business scenario.
The next step is to transform the responsibility chain mode in the previous article and introduce the builder mode.
Builder model:
The core of the builder's design pattern is to hide the internal construction details and realize the construction through the external builder. Builder is responsible for the specific process construction of Product class objects, and Director is responsible for guiding Build and requiring builder to complete the construction of Produt in the specified order. Finally, the built results are returned through builder.
The reason why the builder mode is commonly used is that it exists with the tripartite framework, because the tripartite framework contains more implementation details. Therefore, in order not to see the internal implementation details to the outside, but also to give users better expansion and clean code, this purpose can be achieved only through this way.
Specific code implementation:
The business code at the beginning is the same as that in the previous article.
1. Entities

@Data
public class Member implements Serializable {

    public String loginName;

    public String password;

    public String roleName;

    public Member(String loginName, String password) {
        this.loginName = loginName;
        this.roleName = password;
    }

}


2.Handler implementation. This will be different from the up bias, and the Builder's Builder will be defined more

public abstract class Handler<T> {

    protected Handler next;

    public void next(Handler next){
        this.next = next;
    }


    public abstract void doHandler(Member member);

    public static class Builder<T> {
        private Handler<T>  head;
        private Handler<T> tail;

        public Builder<T> addHandler(Handler<T> handler){
            if(this.head == null){
                this.head = this.tail =handler;
                return this;
            }
            this.tail.next(handler);
            this.tail = handler;
            return  this;
        }

        public Handler<T> build(){
            return this.head;
        }

    }
}


3. The business implementation of each business module remains unchanged
3.1 calibration parameters

public class ValidateHandler extends Handler {

    @Override
    public void doHandler(Member member) {
         String loginName = member.getLoginName();
         if(StringUtils.isEmpty(loginName)){
             System.out.println("User name and password are empty");
             return;
         }
         System.out.println("If the user name and password are not empty, you can proceed");
    }

}


3.2 login service

public class LoginHandler extends Handler {
    @Override
    public void doHandler(Member member) {
        System.out.println("Login succeeded");
        member.setRoleName("administrators");
        next.doHandler(member);
    }
}


3.3 processing of permission business

public class AuthHandler extends Handler {
    @Override
    public void doHandler(Member member) {
        if(!"administrators".equals(member.getRoleName())){
            System.out.println("You are not an administrator,No operation permission");
            return;
        }
        System.out.println("Allow operation");
        next.doHandler(member);
    }

}


4. Implementation of business code. Now we can understand the code handled by the builder pattern here.

public class MemberService {

    public  void  login(String loginName,String password){

        Handler.Builder builder = new Handler.Builder();
        builder.addHandler(new ValidateHandler())
                .addHandler(new LoginHandler())
                .addHandler(new AuthHandler());
        builder.build().doHandler(new Member(loginName,password));


    }

}


5. Test by code

public class Test {

    public static void main(String[] args) {
        MemberService memberService = new MemberService();
        memberService.login("tom","666");
    }
}

Summary:
Advantages of the responsibility chain model:

  • 1. Decouple requests from processing;
  • 2. The request handler (node object) only needs to pay attention to the requests he is interested in and process them. For the requests he is not interested in, he will forward them to the next node
  • 3. It has the function of chain transmission and request processing. The request sender does not need to know the link structure, but only needs to wait for the request processing result
  • 4. The link structure is flexible, and responsibilities can be dynamically added or deleted by changing the link structure;
  • 5. It is easy to extend the new request processing class (node) and conforms to the opening and closing principle

Disadvantages:

  • 1. If the responsibility chain is too long or the processing time is too long, the overall performance will be affected
  • 2. If there is a circular reference to the node object, it will cause an endless loop and lead to system crash

Topics: Java Design Pattern