专业编程基础技术教程

网站首页 > 基础教程 正文

设计模式-责任链模式

ccvgpt 2024-08-20 12:56:11 基础教程 11 ℃

介绍:

职责链模式(chain of responsibility pattern) 定义: 是将链中的每一个节点看着一个对象,每个节点出来的请求均不同,且内部自动维护一个下一节点对象。当一个请求从链式的首段出发时,会沿着链的路径依次传递给每一个节点,直到有对象处理这个请求为止。属于行为模式。

设计模式-责任链模式

在职责链模式中,多个处理器(也就是刚刚定义中说的“节点对象”)依次处理同一个请 求。一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再 传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职 责,所以叫作职责链模式。



使用场景:

在日常生活中责任链模式还是比较常见的,我们工作平时工作中的审批流程。往往都是一级一级的审批的。直到所有的流程审批完成在算审批完成;比如项目中的不同权限的校验,不同的权限校验可以构成一条责任链,请求沿着这条链传递,直到有一个校验器通过或者全部校验失败。


责任链主要是为了解耦请求与处理,客户只需要将请求发送到链路上即可,无需关注处理的处理细节。请求会自动的流转到一个节点直到流程走完。

原理:

职责链模式结构


职责链模式主要包含以下角色:

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接(链上的每个处理者都有一个成员变量来保存对于下一处理者的引用,比如上图中的successor) 。
  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

案例

责任链模式的实现非常简单,每一个具体的处理类都会保存在它之后的下一个处理类。当处理完成后,就会调用设置好的下一个处理类,直到最后一个处理类不再设置下一个处理类,这时处理链条全部完成。

利用责任链模式实现的简单登录验证:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member implements Serializable {
    /**
     * 登录名
     */
    private String loginName;
    /**
     * 登录通行证
     */
    private String loginPass;
    /**
     * 角色名称
     */
    private String roleName;
}
/**
 * 处理程序
 *
 * @date 2024-05-30
 */
public abstract class Handler {
    protected Handler next;
    public void next(Handler next){ this.next = next;}

    public abstract void doHandler(Member member);
}
/**
 * 身份验证处理程序
 *
 * @author yulang
 * @date 2024-05-30
 */
@Slf4j(topic = "authHandler")
public class AuthHandler extends Handler {

    private static final String NAME_ROLE = "管理员";

    /**
     * 处理程序
     *
     * @param member 成员
     */
    @Override
    public void doHandler(Member member) {
        if(!NAME_ROLE.equals(member.getRoleName())){
            log.info("您不是管理员,没有操作权限");
            return;
        }
        log.info("允许操作");
    }
}
/**
 * 登录处理程序
 *
 * @author yulang
 * @date 2024-05-30
 */
@Slf4j(topic = "LoginHandler")
public class LoginHandler extends Handler {

    @Override
    public void doHandler(Member member) {
        log.info("登录成功!");
        member.setRoleName("管理员");
        next.doHandler(member);
    }
}
/**
 * 验证处理程序
 *
 * @author yulang
 * @date 2024-05-30
 */
@Slf4j(topic = "ValidateHandler")
public class ValidateHandler extends Handler {

    @Override
    public void doHandler(Member member) {
        if(StringUtils.isEmpty(member.getLoginName()) ||
                StringUtils.isEmpty(member.getLoginPass())){
           log.info("用户名和密码为空");
            return;
        }
        log.info("用户名和密码不为空,可以往下执行");
        next.doHandler(member);
    }
}
/**
 * 会员服务
 *
 * @author yulang
 * @date 2024-05-30
 */
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.doHandler(new Member(loginName,loginPass,""));

    }

}

测试代码

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

职责链模式的缺点:

  • 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

Tags:

最近发表
标签列表