Java设计模式之责任链模式

本文通过中国古代女性的社会地位变迁,形象地介绍了Java责任链模式的工作原理。通过一系列处理者对象组成的链表,每个处理者负责处理特定类型的请求,并将不符合自身处理条件的请求传递给链中的下一个处理者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java的设计模式有很多种,分说一下Java的责任链模式
责任链模式就是有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一个对象决定处理该请求,所以责任链模式可以实现,在隐瞒客户端的情况,对系统进行动态的调整

通俗的表达责任链

中国古代对妇女制定了“三从四德”的道德规范,“三从”是指“未嫁从父,既嫁从夫,夫死从子”。

也就是说,一位女性在结婚之前要听从于父亲,结婚之后要听从于丈夫,如果丈夫死了还要听从于儿子。举例来说,如果一位女性要出去逛街,在她出嫁前必须征得父亲的同意,出嫁之后必须获得丈夫的许可,可丈夫死了怎么办?那就得问问儿子是否允许自己出去逛街。估计你接下来马上要问:“要是没有儿子怎么办?”那就请示小叔子、侄子等。在父系社会中,妇女只占从属地位,现在想想中国古代的妇女还是挺悲惨的,连逛街都要多番请示。

作为父亲、丈夫以及儿子,只有两种选择,要不承担起责任来,允许她或不允许逛街;要不就让她请示下一个人,这是整个社会体系的约束,应用到我们项目中就是业务规则,下面要看代码。

女性接口

public interface IWomen {
    //获得个人情况 1. 未结婚 2. 已经结婚 3. 丈夫去世 儿子健康
    public int getType();
    //获得个人请示 你要干什么 出去逛街 约会 看电影
    public String getRequest();
}

女性接口仅两个方法,一个是获得当前的个人状况getType,通过返回值决定是结婚了还是没结婚,丈夫是否在世等,另外一个方法getRequest是要请示的内容,要出去逛街还是吃饭,其实现类代码如下:

古代妇女

public class Women implements IWomen {
    /**
     * 通过一个int类型的参数来描述妇女的个人状况
     * 1--未出嫁
     * 2--出嫁
     * 3--丈夫去世
     */
    private int type;
    //妇女的请求
    private String request;
    //构造函数传递过来请求
    public Women(int type, String request) {
        this.type = type;
        switch (this.type){
            case 1:
                this.request = "女儿的请求是:" + request;
                break;
            case 2:
                this.request = "妻子的请求是:" + request;
                break;
            case 3:
                this.request = "母亲的请求是:" + request;
                break;
        }
    }

    //获得自己的状况
    @Override
    public int getType() {
        return this.type;
    }
    //获得妇女的请求
    @Override
    public String getRequest() {
        return this.request;
    }
}

有处理权的人员接口

public abstract class Handler {
    public final static int FATHER_LEVERL_REQUEST = 1;
    public final static int HUSHAND_LEVERL_REQUEST = 2;
    public final static int SON_LEVERL_REQUEST = 3;
    //能处理的级别
    private int level = 0;
    //责任传递 下一个责任人是谁
    private Handler nextHandler;
    //每个类都要说明一下自己能处理哪些请求
    public Handler(int level){
        this.level = level;
    }
    //一个女性(女儿、妻子或者母亲)要求逛街 你要处理这个请求
    public final void HandleMessage(IWomen women){
        if (women.getType() == this.level){
            this.response(women);
        }else {
            //有后续环节 才把请求往后递送
            if (this.nextHandler != null){
                this.nextHandler.HandleMessage(women);
            }
            //已经没有后续处理人了 不用处理
            else {
                System.out.println("没有地方请示了,按不同意处理------\n");
            }
        }
    }

    /**
     * 如果不属于你的处理请求 你应该让她找下一个环节的人 如女儿出嫁了
     * 还向父亲请示是否可以逛街 那父亲应该告诉女儿 应该找丈夫请求
     * @param handler
     */
    public void setNext(Handler handler){
        this.nextHandler = handler;
    }

    //有请示当然要回应
    protected abstract void response(IWomen women);

}

还是比较简单的,其实在这里也用到了模版方法模式,在模版方法中判断请求的级别和当前能够处理的级别,如果相同则调用基本方法,做出反馈;如果不相等,则传递到下一个环节,由下一个环节做出回应,如果已经达到环节尾部,则直接做不同意处理。基本方法response需要各个实现类实现,每个实现类只要实现两个职责:

  1. 定义自己能够处理的级别;
  2. 对请求做出回应

父亲类

public class Father extends Handler {
    //父亲只处理女儿的请求
    public Father() {
        super(Handler.FATHER_LEVERL_REQUEST);
    }

    //父亲的回答
    @Override
    protected void response(IWomen women) {
        System.out.println("------------女儿向父亲请示-------------");
        System.out.println(women.getRequest());
        System.out.println("父亲的回答是:同意\n");
    }
}

丈夫类

public class Husband extends Handler {

    //丈夫只处理妻子的请求
    public Husband() {
        super(Handler.HUSHAND_LEVERL_REQUEST);
    }

    //丈夫请示的回答
    @Override
    protected void response(IWomen women) {
        System.out.println("------------妻子向丈夫请示-------------");
        System.out.println(women.getRequest());
        System.out.println("丈夫的回答是:同意\n");
    }
}

儿子类

public class Son extends Handler {
    //儿子只处理母亲的请求
    public Son() {
        super(Handler.SON_LEVERL_REQUEST);
    }

    //儿子的回答
    @Override
    protected void response(IWomen women) {
        System.out.println("------------母亲向儿子请示-------------");
        System.out.println(women.getRequest());
        System.out.println("儿子的回答是:同意\n");
    }
}

这三个类都很简单,构造方法是必须实现的,父类框定子类必须有一个显式构造函数,子类不实现编译不通过,通过构造方法我们设置了各个类能处理的请求类型

  • Father
    只能处理请求类型为1(也就是女儿)的请求
  • Husband
    只能处理请求类型为2(也就是妻子)的请求
  • Son
    儿子只能处理请求类型为3(也就是母亲)的请求

那如果请求类型为4的该如何处理呢?在Handler中我们已经判断了,如果没有相应的处理者(也就是没有下一个环节),则视为不同意。

都定义好以后,建一个场景类来实现这些场景吧

场景类

public class Client {
    public static void main(String[] args) {
        //随机挑选几位女性
        ArrayList<IWomen> arrayList = new ArrayList<>();
        for (int i = 1; i < 5; i++){
            arrayList.add(new Women(i,"我要出去逛街"));
        }
        //定义三个请示对象
        Handler father = new Father();
        Handler husband = new Husband();
        Handler son = new Son();

        father.setNext(husband);
        husband.setNext(son);

        for (IWomen women : arrayList) {
            father.HandleMessage(women);
        }
    }
}

打印的结果:

------------女儿向父亲请示-------------
女儿的请求是:我要出去逛街
父亲的回答是:同意

------------妻子向丈夫请示-------------
妻子的请求是:我要出去逛街
丈夫的回答是:同意

------------母亲向儿子请示-------------
母亲的请求是:我要出去逛街
儿子的回答是:同意

没有地方请示了,按不同意处理------

最佳实践

在例子中Handler是抽象类,融合了模版方法模式,每个实现类只要实现两个方法,各个实现类只要关注自己的业务逻辑就成了,至于说什么事要自己处理,那就让父类去决定好了,也就是说父类实现了请求传递的功能,子类实现请求的处理。

责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理,但是必须按照链子走,还是要一步步通过,你不做处理就扔给下一个),作为请求者可以不用知道到底是需要谁来处理的(也就是说这个链子是连好的,你只要把启动链子的头,就会往下走),这是责任链模式的核心。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值