设计模式之责任链模式

责任链模式介绍

责任链模式是将链中的每一个节点看成是一个对象,每个节点处理的请求不同,且内部自动维护一个下一个节点对象。当一个请求从链的首端发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求。属于行为型设计模式。

使用场景

责任链模式主要是解耦了请求与处理,客户端只需要将请求发送到链上即可,无需关心请求的具体内容和处理细节,请求会自动进行传递,直至有处理对象进行处理。适用于以下场景:

  • 多个对象可以处理一个请求,但由哪一个对象处理,则在运行时动态决定。
  • 在不明确指定接收者的情况下,向多个对象中的一个提交请求。
  • 可以动态指定一组对象处理请求。

代码示例

利用责任链模式进行数据校验拦截。

抽象处理类(Handler)

结合了建造者模式

package com.example.proxy.designpatten.chain;

/**
 * @author ludengke
 * @title: Handler
 * @projectName alibabatest
 * @description: TODO
 * @date 2024/6/1511:43
 */
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(){
            return this.head;
        }
    }
}

具体处理类

package com.example.proxy.designpatten.chain;

/**
 * @author ludengke
 * @title: AuthHandler
 * @projectName alibabatest
 * @description: TODO
 * @date 2024/6/1511:50
 */
public class AuthHandler extends Handler{
    @Override
    public void doHandle(Member member) {
        if (!"管理员".equals(member.getRoleName())){
            System.out.println("不是管理员,没有操作权限");
            return;
        }
        System.out.println("认证成功,往下执行");
        if (this.chain!=null){
            this.chain.doHandle(member);
        }
    }
}

package com.example.proxy.designpatten.chain;

/**
 * @author ludengke
 * @title: LoginHandler
 * @projectName alibabatest
 * @description: TODO
 * @date 2024/6/1511:48
 */
public class LoginHandler extends Handler{
    @Override
    public void doHandle(Member member) {
        System.out.println("登录成功");
        member.setRoleName("管理员");
        if (this.chain!=null){
            this.chain.doHandle(member);
        }    }
}

package com.example.proxy.designpatten.chain;

import org.springframework.util.StringUtils;

/**
 * @author ludengke
 * @title: ValidateHandler
 * @projectName alibabatest
 * @description: TODO
 * @date 2024/6/1511:45
 */
public class ValidateHandler extends Handler{
    @Override
    public void doHandle(Member member) {
        if (member==null
                || StringUtils.isEmpty(member.getName())
                ||StringUtils.isEmpty(member.getPwd())){
            System.out.println("用户或密码为空");
            return;
        }
        System.out.println("用户密码校验成功,往下执行");
        if (this.chain!=null){
            this.chain.doHandle(member);
        }    }
}

客户端

package com.example.proxy.designpatten.chain;

/**
 * @author ludengke
 * @title: MemberService
 * @projectName alibabatest
 * @description: TODO
 * @date 2024/6/1511:42
 */
public class MemberService {
    public void login(String name,String pwd){
        Member member=new Member();
        member.setName(name);
        member.setPwd(pwd);
        Handler.Builder builder=new Handler.Builder();
        builder.addHandler(new ValidateHandler())
                .addHandler(new LoginHandler())
                .addHandler(new AuthHandler());
        //返回head,就是返回整个链
        builder.build().doHandle(member);
    }
}

测试类

package com.example.proxy.designpatten.chain;

/**
 * @author ludengke
 * @title: TestChain
 * @projectName alibabatest
 * @description: TODO
 * @date 2024/6/1511:53
 */
public class TestChain {
    public static void main(String[] args) {
        MemberService memberService=new MemberService();
        memberService.login("ss","ss");
    }
}

责任链模式的优缺点

优点

  • 将请求与处理解耦。
  • 请求处理者(链中的节点对象)只需要关注请求的处理,对于不感兴趣的请求,转发给下个请求对象即可。
  • 具备链式传递处理请求的功能,请求发送者不需要知道链路结构,只需要等待处理结果。
  • 链式结构灵活,可以通过改变链的调用结构,动态增删责任。
  • 易于扩展,可以加新的责任,符合开闭原则。

缺点

  • 责任链太长,处理时间可能过长。
  • 如果节点对象出现循环引用,可能导致死循环,使系统崩溃。
内容简介: 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计模式的基础。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。本章将详细介绍开闭原则(OCP)、依赖倒置原则(DIP)、单一职责原则(SRP)、接口隔离原则(ISP)、迪米特法则(LoD)、里氏替换原则(LSP)、合成复用原则(CARP)的具体内容。 为什么需要学习这门课程? 你在日常的开发中,会不会也遇到过同样的问题。系统出现问题,不知道问题究竟出在什么位置;当遇到产品需求,总是对代码缝缝补补,不能很快的去解决。而且平时工作中,总喜欢把代码堆在一起,出现问题时,不知道如何下手,工作效率很低,而且自己的能力也得不到提升。而这些都源于一个问题,那就是软件设计没做好。这门课能帮助你很好的认识设计模式,让你的能力得到提升。课程大纲: 为了让大家快速系统了解设计模式知识全貌,我为您总结了思维导图,帮您梳理学习重点,建议收藏!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值