zoukankan      html  css  js  c++  java
  • 设计模式-责任链模式

    设计模式-责任链模式

    定义

    责任链模式(Chain of Responsibility Pattern)是将链中的每一个节点当做一个对象,每个节点处理的请求不同,且内部自动维护一个下一个节点的对象。当一个请求从链的首端出发时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止。

    属于行为模式

    适用场景

    1. 多个对象可以处理一个请求,但具体由哪个对象处理由动态决定。
    2. 在不指定明确接收者的情况下,向多个对象中的一个提交一个请求。
    3. 可动态地指定一组对象处理请求

    代码示例

    普通写法

    拿处理请求举例:

    1. 定义 Handler 抽象类,提供设置下一 handler 方法
    package com.black.design.pattern.responsibilitychain.general;
    
    // 抽象类
    public abstract class Handler {
    
        protected Handler sucessor;
        
        public  void setNextHandler(Handler sucessor) {
            this.sucessor = sucessor;
        }
    
        public abstract  void handleRequest(String request) ;
        
    }
    
    
    1. 定义 ConcreHandlerA 类,只能处理 requestA 请求,其他请求则让下一个处理类处理
    package com.black.design.pattern.responsibilitychain.general;
    
    public class ConcreHandlerA extends Handler {
    
        @Override
        public void handleRequest(String request) {
    
            if("requestA".equals(request)) {
                System.out.println(this.getClass().getSimpleName() +  "handle with request [" +request +"]");
                return;
            }
            if (this.sucessor != null) {
                sucessor.handleRequest(request);
            }
        }
    
    }
    
    
    1. 定义 ConcreHandlerB 类,只能处理 requestB 请求,其他请求则让下一个处理类处理
    package com.black.design.pattern.responsibilitychain.general;
    
    public class ConcreHandlerB extends Handler {
    
        @Override
        public void handleRequest(String request) {
            if("requestB".equals(request)) {
                System.out.println(this.getClass().getSimpleName() +  "handle with request [" +request +"]");
                return;
            }
            if (this.sucessor != null) {
                sucessor.handleRequest(request);
            }
        }
    
    }
    
    
    1. 测试
    package com.black.design.pattern.responsibilitychain.general;
    //测试类
    public class HandlerTest {
        
        public static void main(String[] args) {
    		// 实例化 handlerA 处理类
            Handler handlerA = new ConcreHandlerA();
    		// 实例化 handlerB 处理类
            Handler handlerB = new ConcreHandlerB();
            // handlerA 下一节点是 handlerB 处理类
            handlerA.setNextHandler(handlerB);
            // 定义 3 个请求
            String[] reqs = {"requestA","requestB","requestC"};
            // 循环处理
            for (int i = 0; i < reqs.length; i++) {
                handlerA.handleRequest(reqs[i]);
            }
           
        }
    }
    
    

    结果:

    ConcreHandlerAhandle with request [requestA]
    ConcreHandlerBhandle with request [requestB]
    

    登录场景

    基本流程:

    1. 验证用户名和密码是否为空
    2. 登录验证,成功后获取用户权限
    3. 验证权限

    代码如下:

    1. 登录接口
    
    package com.black.design.pattern.responsibilitychain.auth;
    
    // 登录接口类
    public interface LoginService {
    
        // 根据用户名和密码登录
        public void login(String userName, String password);
    }
    
    package com.black.design.pattern.responsibilitychain.auth;
    
    // 登录接口实现类
    public class LoginServiceImpl implements LoginService {
    
        public void login(String userName, String password) {
            // 校验用户名密码是否为null 
            Handler vHandler = new ValidatorHandler();
            // 登录
            Handler loginHandler = new LoginHandler();
            // 校验是否有权限
            Handler authHandler = new AuthHandler();
            //执行
            vHandler.next(loginHandler);
            loginHandler.next(authHandler);
            vHandler.doHandle(new UserInfo(userName, password));
        }
    }
    
    package com.black.design.pattern.responsibilitychain.auth;
    
     // 用户信息
    public class UserInfo {
        // 用户名
        private String userName;
        // 密码
        private String password;
        // 角色
        private String role;
    
        public UserInfo(String userName, String password) {
            this.userName = userName;
            this.password = password;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getRole() {
            return role;
        }
    
        public void setRole(String role) {
            this.role = role;
        }
    }
    
    
    
    1. 创建抽象处理类
    package com.black.design.pattern.responsibilitychain.auth;
    
    // 处理类
    public abstract class Handler {
    
        // 下一处理类
        protected Handler nextHandler;
        
        // 处理方法
        protected  abstract void doHandle(UserInfo userInfo) ;
        
    	// 设置下一处理
        public void next(Handler h) {
            this.nextHandler = h;
        }
    }
    
    
    1. 登录参数校验处理类
    package com.black.design.pattern.responsibilitychain.auth;
    
    // 登录参数验证处理类
    public class ValidatorHandler extends Handler {
    
        @Override
        protected void doHandle(UserInfo userInfo) {
            // 校验参数
            if(userInfo.getUserName() == null || 
                    userInfo.getPassword() == null) {
                System.out.println("用户名或密码为空,不允许登录!");
                return;
            }
            System.out.println("用户名和密码不为空,继续");
           nextHandler.doHandle(userInfo);
        }
    
    }
    
    
    1. 登录处理类
    package com.black.design.pattern.responsibilitychain.auth;
    
    // 登录处理类
    public class LoginHandler extends Handler {
    
        @Override
        protected void doHandle(UserInfo userInfo) {
    
            System.out.println("登录成功!");
            // 登录成功设置用户权限
            //userInfo.setRole("业务员");
            userInfo.setRole("管理员");
            nextHandler.doHandle(userInfo);
        }
    }
    
    
    1. 权限验证处理类
    package com.black.design.pattern.responsibilitychain.auth;
    
    // 权限验证处理类
    public class AuthHandler extends Handler {
    
        @Override
        protected void doHandle(UserInfo userInfo) {
    
            if(!"管理员".equals(userInfo.getRole())) {
                System.out.println("您不是管理员,没有操作权限");
                return;
            }
            System.out.println("允许操作");
        }
    
    }
    
    

    测试类

    package com.black.design.pattern.responsibilitychain.auth;
    
    // 测试类
    public class AuthTest {
    
        public static void main(String[] args) {
            LoginService loginService = new LoginServiceImpl();
            loginService.login("black", "abc");
        }
    }
    
    

    测试结果:

    用户名和密码不为空,继续
    登录成功!
    允许操作
    
    


    优化版

    主要优化点: 增加 Handler Builder 类,用于构建 Handler 处理链。只需要调整 Handler 类和 LoginServiceImpl 类即可。

    package com.black.design.pattern.responsibilitychain.auth;
    
    // 处理类
    public abstract class Handler {
    
        // 下一处理类
        protected Handler nextHandler;
        
        // 处理
        protected  abstract void doHandle(UserInfo userInfo) ;
        
        public void next(Handler h) {
            this.nextHandler = h;
        }
        
        // 用于构建 handler 处理链
        public static  class Builder{
            
            private Handler first;// 首节点
            
            private Handler last;// 尾节点
            
            // 设置下一节点
            public Builder next(Handler handler) {
                if(first == null ) {
                    // 如果 首节点是null 那么 handler 就是第一个节点
                    first = last = handler;
                }
                // 如果 首节点不是null 那么 handler 就加入到最后一个节点
                last.next(handler);
                last = handler;
                return this;
            }
            
            public Handler build() {
                // 每次返回链的首节点
                return first;
            }
        }
    }
    
    
    package com.black.design.pattern.responsibilitychain.auth;
    
    // 登录接口实现类
    public class LoginServiceImpl implements LoginService {
    
        public void login(String userName, String password) {
            // 校验用户名密码是否为null 
            Handler vHandler = new ValidatorHandler();
            // 登录
            Handler loginHandler = new LoginHandler();
            // 校验是否有权限
            Handler authHandler = new AuthHandler();
            
            // 构建 handler 处理链
            Handler.Builder builder = new  Handler.Builder();
            builder.next(vHandler).next(loginHandler).next(authHandler);
            
         
            builder.build().doHandle(new UserInfo(userName, password));
        }
    }
    
    

    测试结果:

    用户名和密码不为空,继续
    登录成功!
    允许操作
    
    
  • 相关阅读:
    近期文章与教程和其他情况说明
    Python从入门到精通--课程目录
    第四天:创建型模式--原型模式
    python api链接数据库
    Delphi 实现简易语音发音(基于TTS方式)
    delphi下运行vbscript脚本
    使用PaxScript为Delphi应用增加对脚本的支持
    delphi与javascript互通
    奇技淫巧之Delphi和JavaScript互通
    在delphi中执行javascript代码
  • 原文地址:https://www.cnblogs.com/lihw-study/p/15221439.html
Copyright © 2011-2022 走看看