Java设计模式——责任链模式

当一个请求需要在多个对象之间传递,每个对象都可能处理该请求或将其传递给下一个对象。在这种情况下,需要避免将发送者与接收者之间的耦合,以及确定请求的处理方式。此时可使用责任链模式,它的优点有降低耦合度(无需关心哪个对象会处理请求),灵活性(可以动态地改变它们之间的顺序和职责),可扩展性(添加新的处理者,而不会影响现有代码),可维护性(处理者之间职责分开,便于维护);责任链模式也有限制,比如可能导致请求无法被处理或者处理链太长而导致性能问题。

一、抽象类方式实现

假定一个权限认证的例子

java 复制代码
/**
 * 成员类
 */
@Getter
@ToString
public class Member {
    private String loginName;
    private String loginPass;
    @Setter
    private String roleName;

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


/**
 * 抽象处理者
 */
public abstract class Handler {
    protected Handler handler;

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

    public abstract void doHandler(Member member);
}


/**
 * 认证处理器
 */
public class AuthHandler extends Handler {
    @Override
    public void doHandler(Member member) {
        if (!"管理员".equals(member.getRoleName())) {
            System.out.println("无操作权限!");
            return;
        }
        System.out.println("操作成功,管理员同志");
    }
}


/**
 * 登陆处理器
 */
public class LoginHandler extends Handler {
    @Override
    public void doHandler(Member member) {
        System.out.println("登陆成功!");
        member.setRoleName("管理员");
        handler.doHandler(member);
    }
}


/**
 * 校验数据处理器
 */
public class ValidDataHandler extends Handler {
    @Override
    public void doHandler(Member member) {
        if (StringUtils.isBlank(member.getLoginName()) || StringUtils.isBlank(member.getLoginPass())) {
            System.out.println("用户名或密码不能为空!");
            return;
        }
        System.out.println("验证通过!");
        handler.doHandler(member);
    }
}


/**
 * 业务服务类
 */
public class MemberService {

    public void login(String loginName, String loginPass) {
        Handler validDateHandler = new ValidDataHandler();
        Handler loginHandler = new LoginHandler();
        Handler authHandler = new AuthHandler();

        validDateHandler.next(loginHandler);
        loginHandler.next(authHandler);

        validDateHandler.doHandler(new Member(loginName, loginPass));
    }

}

编写测试用例

java 复制代码
    /**
     * 责任链模式-权限认证测试
     */
    @Test
    public void testPermission() {
        MemberService memberService = new MemberService();
        memberService.login("admin", "123456");
    }

二、与建造者模式相结合

还是权限认证的例子

java 复制代码
/**
 * 抽象处理者(结合建造者模式)
 */
public abstract class HandlerUp {
    protected HandlerUp handler;

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

    public abstract void doHandler(Member member);

    public static class Builder {
        private HandlerUp head;
        private HandlerUp tail;

        public Builder addHandler(HandlerUp handler) {
            if (this.head == null) {
                this.head = this.tail = handler;
                return this;
            }
            this.tail.next(handler);
            this.tail = handler;

            return this;
        }

        public HandlerUp build() {
            return this.head;
        }
    }
}


/**
 * 认证处理器
 */
public class AuthHandlerUp extends HandlerUp {
    @Override
    public void doHandler(Member member) {
        if (!"管理员".equals(member.getRoleName())) {
            System.out.println("非管理员,无操作权限!");
            return;
        }
        System.out.println("操作成功,管理员同志");
    }
}


/**
 * 登陆处理器
 */
public class LoginHandlerUp extends HandlerUp {
    @Override
    public void doHandler(Member member) {
        System.out.println("登陆成功!");
        member.setRoleName("管理员");
        handler.doHandler(member);
    }
}


/**
 * 校验数据处理器
 */
public class ValidDataHandlerUp extends HandlerUp {
    @Override
    public void doHandler(Member member) {
        if (StringUtils.isBlank(member.getLoginName()) || StringUtils.isBlank(member.getLoginPass())) {
            System.out.println("用户名或密码不能为空!");
            return;
        }
        System.out.println("用户名和密码校验成功!");
        handler.doHandler(member);
    }
}


/**
 * 业务服务类
 */
public class MemberServiceUp {

    public void login(String loginName, String loginPass) {
        new HandlerUp.Builder()
                .addHandler(new ValidDataHandlerUp())
                .addHandler(new LoginHandlerUp())
                .addHandler(new AuthHandlerUp())
                .build()
                .doHandler(new Member(loginName, loginPass));
    }

}

编写测试用例

java 复制代码
    /**
     * 责任链模式-权限认证(增强版)测试
     */
    @Test
    public void testPermissionUp() {
        MemberServiceUp memberServiceUp = new MemberServiceUp();
        memberServiceUp.login("admin", "123456");
    }
相关推荐
天天摸鱼的java工程师20 分钟前
Java 解析 JSON 文件:八年老开发的实战总结(从业务到代码)
java·后端·面试
白仑色21 分钟前
Spring Boot 全局异常处理
java·spring boot·后端·全局异常处理·统一返回格式
喵手28 分钟前
反射机制:你真的了解它的“能力”吗?
java·后端·java ee
kaika138 分钟前
告别复杂配置!使用 1Panel 运行环境功能轻松搭建 Java 应用
java·1panel·建站·halo
有梦想的攻城狮1 小时前
Java 11中的Collections类详解
java·windows·python·java11·collections
六千江山1 小时前
从字符串中提取符合规则的汽车车牌
java
33255_40857_280591 小时前
从韩立结婴看Java进阶:一个10年老码农的修仙式成长指南
java
赵星星5201 小时前
透彻理解Java中的深拷贝与浅拷贝:从误区到最佳实践
java·后端
心月狐的流火号1 小时前
Java CompletableFuture 核心API
java
黑客影儿1 小时前
Java技术总监的成长之路(技术干货分享)
java·jvm·后端·程序人生·spring·tomcat·maven