This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

This article is excerpted from Tom Tan, author of This is How Design Patterns Should Be Learned.

1 Configure hot swap permission control in responsibility chain mode

Start by creating an entity class Member.


public class Member {
    private String loginName;
    private String loginPass;
    private String roleName;

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

    public String getLoginName(a) {
        return loginName;
    }

    public String getLoginPass(a) {
        return loginPass;
    }

    public String getRoleName(a) {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    @Override
    public String toString(a) {
        return "Member{" +
                "loginName='" + loginName + '\' ' +
                ", loginPass='" + loginPass + '\' ' +
                '} '; }}Copy the code

And then let’s look at a piece of code that we write all the time.


public class MemberService {

    public void login(String loginName,String loginPass){
        if(StringUtils.isEmpty(loginName) ||
                StringUtils.isEmpty(loginPass)){
            System.out.println("User name and password verification successful, can proceed.");
            return;
        }
        System.out.println("Username and password not empty, can be run down");

        Member member = checkExists(loginName,loginPass);
        if(null == member){
            System.out.println("User does not exist");
            return;
        }
        System.out.println("Login successful!");

        if(!"Administrator".equals(member.getRoleName())){
            System.out.println("You're not an administrator, you don't have access.");
            return;
        }
        System.out.println("Allowed operation");

    }

    private Member checkExists(String loginName,String loginPass){
        Member member = new Member(loginName,loginPass);
        member.setRoleName("Administrator");
        return member;
    }

    public static void main(String[] args) {
        MemberService service = new MemberService();
        service.login("tom"."666"); }}Copy the code

In the above code, the main data verification before login. Its logic of judgment is sequential. First make a non-short judgment, then check whether the account is valid, and finally get the user role. Check whether the user has operation rights based on the rights of the user role. Such inspection code is generally essential, but writing in specific business code is very bloated, so we can use the chain of responsibility mode to connect these inspection steps, and does not affect the beauty of the code, so that we can pay more attention to a specific business logic processing when coding. To optimize the code using the chain of responsibility pattern, start by creating a Handler class.


public abstract class Handler {
    protected Handler chain;

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

    public abstract void doHandle(Member member);

}

Copy the code

Then create a non-null ValidateHandler class, a LoginHandler class, and a permission AuthHandler class, respectively. The code for the ValidateHandler class is shown below.


public class ValidateHandler extends Handler {
    public void doHandle(Member member) {
        if(StringUtils.isEmpty(member.getLoginName()) ||
        StringUtils.isEmpty(member.getLoginPass())){
            System.out.println("User name or password is empty");
            return;
        }
        System.out.println("User name and password verification successful, can proceed."); chain.doHandle(member); }}Copy the code

The code for the LoginHandler class is as follows.


public class LoginHandler extends Handler {

    public void doHandle(Member member) {
        System.out.println("Login successful!");
        member.setRoleName("Administrator"); chain.doHandle(member); }}Copy the code

The code for the AuthHandler class is as follows.


public class AuthHandler extends Handler {

    public void doHandle(Member member) {
        if(!"Administrator".equals(member.getRoleName())){
            System.out.println("You're not an administrator, you don't have access.");
            return;
        }
        System.out.println("You are the administrator. Permission to operate."); }}Copy the code

Then modify the code in MemberService, in fact, only need to define several handlers in series according to the business requirements, to form a chain.


public class MemberService {
    public void login(String loginName,String loginPass){
        Handler validateHandler = new ValidateHandler();
        Handler loginHandler = new LoginHandler();
        Handler authHandler = new AuthHandler();

        validateHandler.next(loginHandler);
        loginHandler.next(authHandler);

        validateHandler.doHandle(newMember(loginName,loginPass)); }}Copy the code

Finally write the client call code.


public class Test {
    public static void main(String[] args) {
        MemberService service = new MemberService();
        service.login("tom"."666"); }}Copy the code

The running result is shown in the figure below.

In fact, we usually use a lot of authority verification framework is the use of this principle, the various dimensions of the authority to understand the coupling and then series together, only to deal with their respective related responsibilities. If the responsibility is not relevant to you, it is passed to the next Handler on the chain.

The responsibility chain mode is used in combination with the builder mode

Because the chain of responsibility mode has a chain structure, and in the above code, the role responsible for assembling the chain structure is MemberService. When the chain structure is long, the work of MemberService is very cumbersome, and the code of MemberService is relatively bloated, and the handler or message type is changed later, All must be modified in MemberService, which does not match the open and close principle. The reason for these problems is that the assembly of chain structure is too complex, and for the creation of complex structure, we naturally think of the builder mode, using the builder mode, can fully automatic chain assembly of the processing node object specified by MemberService, the customer only needs to specify the processing node object, Nothing else matters, and the chain structure is constructed differently depending on the order in which the client specifies the node objects to be processed. So let’s change it up a little bit. Let’s change the Handler code first.


public abstract class Handler<T> {
    protected Handler chain;

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

    public abstract void doHandle(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(a) {
            return this.head; }}}Copy the code

Then modify the MemberService code.


public class MemberService {
    public void login(String loginName,String loginPass){

        Handler.Builder builder = new Handler.Builder();
        builder.addHandler(new ValidateHandler())
                .addHandler(new LoginHandler())
                .addHandler(new AuthHandler());

        builder.build().doHandle(newMember(loginName,loginPass)); }}Copy the code

Since Builder mode builds node handlers, we use Builder as the static inner class of Handler, and since the client does not need to do chain assembly, we can also make the chain assembly method next() method private to make Handler more aggregated, as shown below.


public abstract class Handler<T> {
    protected Handler chain;

    private void next(Handler handler){
        this.chain = handler; }... }Copy the code

Through this case, friends should have felt the essence of the chain of responsibility and the combination of the builder.

This article is “Tom play structure” original, reproduced please indicate the source. Technology is to share, I share my happiness! If this article is helpful to you, welcome to follow and like; If you have any suggestions can also leave a comment or private letter, your support is my motivation to adhere to the creation. Pay attention to “Tom bomb architecture” for more technical dry goods!

Collect this article, equivalent to collect a “design patterns” book

“Welcome to the discussion in the comments section. The excavation authorities will draw 100 nuggets in the comments section after project Diggnation. See the event article for details.”