责任链设计模式(一) - 定义及使用

前言

责任链设计模式系列文章
责任链设计模式(一) - 定义及使用
责任链设计模式(二) - 使用场景

1. 定义?


使多个对象都有机会处理请求,将这些对象连成一条链子,并且沿着这条链子处理该请求,直到有对象处理它为止;

2. 举例说明


比如还是早期的微信登录,比如有3个用户系统的账号密码都可以登录,微信用户系统、qq用户系统、农药用户系统。
思路如下
1>:定义用户处理接口 IUserSystem,定义queryUserInfo(userName, userPwd)方法,用于根据用户名和密码查询用户信息;
2>:定义责任链设计模式的接口 IUserSystemHandler,用于获取下一个用户系统的handler;
3>:定义抽象处理者角色 AbsUserSystemHandler,让其实现上边两个接口,重写两个方法,获取下一个系统的getNextHandler()方法 和 设置下一个系统的 nextHandler()方法;
4>:让微信用户系统继承抽象类 AbsUserSystemHandler,让其实现 queryUserInfo(),查询的方式是:
a:首先是自己利用for循环查询,如果有返回userInfo信息,就直接返回;
b:如果没有,就调用 getNextHandler()获取下一个用户系统,然后调用nextHandler.queryUserInfo(),继续去查询用户信息,如果有就返回,如果没有就返回null即可;
qq用户系统、农药用户系统查询用户信息方式和4>一样,都是先遍历for循环,如果没有就让下一个用户系统查询;

3. 代码如下


1>:定义用户处理接口 IUserSystem,定义queryUserInfo(userName, userPwd)方法,用于根据用户名和密码查询用户信息
/**
 * Email: 2185134304@qq.com
 * Created by Novate 2018/6/9 9:17
 * Version 1.0
 * Params:
 * Description:    校验用户的处理接口
*/

public interface IUserSystem {

    /**
     * 根据用户名和密码查询用户信息
     */
    public UserInfo queryUserInfo(String userName , String userPwd) ;
}
2>:定义责任链设计模式的接口 IUserSystemHandler,用于获取下一个用户系统的handler:
/**
 * Email: 2185134304@qq.com
 * Created by Novate 2018/6/9 9:13
 * Version 1.0
 * Params:
 * Description:    责任链设计模式 - 抽象处理者角色接口
*/

public interface IUserSystemHandler<T extends IUserSystemHandler> {

    /**
     * 获取下一个系统的handler
     */
    void nextHandler(T systemHandler) ;
}
3>:定义抽象处理者角色 AbsUserSystemHandler,让其实现上边两个接口,重写两个方法,获取下一个系统的getNextHandler()方法 和 设置下一个系统的 nextHandler()方法:
/**
 * Email: 2185134304@qq.com
 * Created by Novate 2018/6/9 9:11
 * Version 1.0
 * Params:
 * Description:    责任链设计模式 - 抽象处理者角色
*/

public abstract class AbsUserSystemHandler implements IUserSystemHandler<AbsUserSystemHandler> , IUserSystem{

    private AbsUserSystemHandler nextHandler ;

    /**
     * 获取下一个系统
     */
    public AbsUserSystemHandler getNextHandler() {
        return nextHandler;
    }


    /**
     * 如果微信用户系统没有查到信息,就设置下一个系统,是qq用户系统
     * 如果qq用户系统没有查到信息,就设置下一个系统,是农药用户系统
     * 如果还有下一个用户系统,会去设置下一个系统...
     */
    public void nextHandler(AbsUserSystemHandler nextHandler) {
        this.nextHandler = nextHandler;
    }
}
4>:让微信用户系统继承抽象类 AbsUserSystemHandler,让其实现 queryUserInfo(),查询的方式是:

a:首先是自己利用for循环查询,如果有返回userInfo信息,就直接返回;
b:如果没有,就调用 getNextHandler()获取下一个用户系统,然后调用nextHandler.queryUserInfo(),继续去查询用户信息,如果有就返回,如果没有就返回null即可;
qq用户系统、农药用户系统查询用户信息方式和4>一样,都是先遍历for循环,如果没有就让下一个用户系统查询;

微信用户系统如下:
/**
 * Email: 2185134304@qq.com
 * Created by Novate 2018/6/3 11:10
 * Version 1.0
 * Params:
 * Description:    微信的用户系统 - 数组存储 - 不需要暴露数组,直接暴露一个迭代器iterator()方法给外部即可
*/

public class WXUserSystem extends AbsUserSystemHandler{
    UserInfo[] userInfos ;

    public WXUserSystem(){
        userInfos = new UserInfo[3] ;
        userInfos[0] = new UserInfo("Novate","123456","001","男") ;
        userInfos[1] = new UserInfo("景甜","123456","002","女") ;
        userInfos[2] = new UserInfo("江疏影","123456","003","男") ;
    }


    /**
     * 查询用户信息
     *      首先是自己利用for循环遍历,看是否有userInfo信息:
     *      如果有,就返回;
     *      如果没有,就获取下一个用户系统,让下一个用户系统继续根据用户名和密码查询
     */
    @Override
    public UserInfo queryUserInfo(String userName, String userPwd) {
        for (UserInfo userInfo : userInfos) {
            if (userInfo.userName.equals(userName) && userInfo.userPwd.equals(userPwd)){
                return userInfo ;
            }
        }

        AbsUserSystemHandler nextHandler = getNextHandler();
        if (nextHandler != null) {
            return nextHandler.queryUserInfo(userName, userPwd);
        }

        return null ;
    }
}
qq用户系统如下:
/**
 * Email: 2185134304@qq.com
 * Created by Novate 2018/6/3 11:09
 * Version 1.0
 * Params:
 * Description:    QQ用户系统 - list集合存储 - 不需要暴露list集合,直接暴露一个迭代器iterator()方法给外部即可
*/

public class QQUserSystem extends AbsUserSystemHandler{
    private List<UserInfo> userInfos ;

    public QQUserSystem(){
        userInfos = new ArrayList<>() ;
        userInfos.add(new UserInfo("Novate","123456","001","男")) ;
        userInfos.add(new UserInfo("王子文","123456","002","女")) ;
        userInfos.add(new UserInfo("世道无情","123456","003","男")) ;
    }


    /**
     * 查询用户信息
     *      首先是自己利用for循环遍历,看是否有userInfo信息:
     *      如果有,就返回;
     *      如果没有,就获取下一个用户系统,让下一个用户系统继续根据用户名和密码查询
     */
    @Override
    public UserInfo queryUserInfo(String userName, String userPwd) {
        for (UserInfo userInfo : userInfos) {
            if (userInfo.userName.equals(userName) && userInfo.userPwd.equals(userPwd)){
                return userInfo ;
            }
        }

        AbsUserSystemHandler nextHandler = getNextHandler();
        if (nextHandler != null) {
            return nextHandler.queryUserInfo(userName, userPwd);
        }

        return null ;
    }
}
农药用户系统如下:
/**
 * Email: 2185134304@qq.com
 * Created by Novate 2018/6/9 9:26
 * Version 1.0
 * Params:
 * Description:    农药用户系统
*/

public class NYUserSystem extends AbsUserSystemHandler {

    private List<UserInfo> userInfos;

    public NYUserSystem(){
        userInfos = new ArrayList<>();
        userInfos.add(new UserInfo("Novate","123456","001","男"));
        userInfos.add(new UserInfo("王子文","123456","002","女"));
        userInfos.add(new UserInfo("吴京","123456","003","男"));
    }



    /**
     * 查询用户信息
     *      首先是自己利用for循环遍历,看是否有userInfo信息:
     *      如果有,就返回;
     *      如果没有,就获取下一个用户系统,让下一个用户系统继续根据用户名和密码查询
     */
    @Override
    public UserInfo queryUserInfo(String userName, String userPwd) {
        for (UserInfo userInfo : userInfos) {
            if (userInfo.userName.equals(userName) && userInfo.userPwd.equals(userPwd)){
                return userInfo ;
            }
        }

        AbsUserSystemHandler nextHandler = getNextHandler();
        if (nextHandler != null) {
            return nextHandler.queryUserInfo(userName, userPwd);
        }

        return null ;
    }
}
5>:测试类如下
/**
 * Email: 2185134304@qq.com
 * Created by Novate 2018/6/3 11:23
 * Version 1.0
 * Params:
 * Description:    责任链设计模式写法
*/

public class Client {
    public static void main(String[] args){
        // 根据用户名和密码查询用户信息 ,
        // 如果没有查询到,那么代表登录失败;如果查询到了,代表登录成功

        QQUserSystem qqUserSystem = new QQUserSystem() ;
        WXUserSystem wxUserSystem = new WXUserSystem() ;
        NYUserSystem nyUserSystem = new NYUserSystem() ;

        // 责任链设计模式,不断的获取下一个系统,直到最后一个系统为止
        wxUserSystem.nextHandler(qqUserSystem);
        qqUserSystem.nextHandler(nyUserSystem);

        // 如果有数据,就返回;如果没有,就返回null
        UserInfo userInfo = wxUserSystem.queryUserInfo("Novate", "123456");

        // UserInfo{userName='Novate', userPwd='123456', userId='001', userSex='男'}
        System.out.println(userInfo);

    }
}
测试的流程是:

a:首先从微信用户系统根据用户名和密码查询,如果查询到信息,就返回;
b:如果没有查询到对应用户信息,就继续从qq用户系统查询,如果查询到信息,就返回;
c:如果没有查询到,就继续从农药中根据用户名和密码查询,如果查询到信息,就返回,如果没有就返回null;

如果以后有更多系统,只需要调用下一个用户系统即可;

 wxUserSystem.nextHandler(qqUserSystem);
qqUserSystem.nextHandler(nyUserSystem);
在这里对应定义就是:

让微信系统、qq系统、农药系统和更多的系统,都有机会去查询用户信息,使用nextHandler()把这些对象连接成一条链子,并且沿着这条链子查询用户信息,直到有系统可以查询到用户信息为止;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容