ITPub博客

首页 > IT职业 > IT生活 > 我的Java设计模式-责任链模式

我的Java设计模式-责任链模式

IT生活 作者:lvxfcjf 时间:2021-09-09 09:47:21 0 删除 编辑

今天来说说程序员小猿和产品就关于需求发生的故事。前不久,小猿收到了产品的需求。

产品经理:小猿,为了迎合大众屌丝用户的口味,我们要放一张图,要露点的。

小猿:......露点?你大爷的,让身为正义与纯洁化身的我做这种需求,还露点。

产品经理:误会误会,是放一张暴露一点点的,尺寸不大。

小猿:尼玛~能说清楚些吗,需求模棱两可的。不干,我要上报boss。

产品经理也一阵无语,这豆丁的事还上报boss。话说这上报也得走程序是吧,技术经理就不干了,“凭什么要跳过我,得经过我才能到boss”。咦~这一层一层上报就涉及到这次的责任链模式。

一、责任链模式

定义

  创建多个对象,使这些对象形成一条链,并沿着这条链传递请求,直到链上的某一个对象决定处理此请求。

特点

1)接收请求的对象连接成一条链,对象之间存在层级关系。

2)这些对象可处理请求,也可传递请求,直到有对象处理该请求。

UML

图片描述

责任链模式涉及到的角色如下所示:

  - 抽象处理者角色:定义了处理请求的接口或者抽象类,提供了处理请求的的方法和设置下一个处理者的方法。

  - 具体处理者角色:实现或者继承抽象这角色,具体逻辑根据实际的架构来定,后面会提到。

二、实战

先来看抽象处理者角色代码:

public abstract class Handler {    private Handler nextHandler;    private int level;    public Handler(int level) {        this.level = level;    }    // 处理请求传递,注意final,子类不可重写    public final void handleMessage(Demand demand) {        if (level == demand.demandLevel()) {            this.report(demand);        } else {            if (this.nextHandler != null) {                System.out.println("事情太严重,需报告上一级");                this.nextHandler.handleMessage(demand);            } else {                System.out.println("我就是boss,没有上头");            }        }    }    public void setNextHandler(Handler handler) {        this.nextHandler = handler;    }    // 抽象方法,子类实现    public abstract void report(Demand demand);}

在抽象处理者角色定义了处理请求的抽象方法,以及下一级传递的对象方法,重点在handleMessage处理请求传递的方法,下面会解释为什么要这样写,继续往下看。

下面是具体处理者角色,继承抽象处理者角色,在我们情景中有两个具体处理者,分别是技术经理和boss。

// 技术经理public class TechnicalManager extends Handler {    public TechnicalManager() {        super(1);    }    @Override    public void report(Demand demand) {        System.out.println("需求:" + demand.detail());        System.out.println(getClass().getSimpleName() + ":小猿我挺你,这个需求不干");    }}// bosspublic class Boss extends Handler {    public Boss() {        super(2);    }    @Override    public void report(Demand demand) {        System.out.println("需求:" + demand.detail());        System.out.println(getClass().getSimpleName() + ":你们打一架吧,打赢的做决定");    }}

可以看到具体处理者的代码很简洁,重写了report方法,实现各自的业务逻辑,这都归功于父类中handleMessage这个方法。

两个角色都定义好了,来看客户端如何实现:

public class Client {    public static void main(String[] args) {        Demand demandA = new DemandA(); // 请求等级低        Demand demandB = new DemandB(); // 请求等级高        Boss boss = new Boss();        TechnicalManager technicalManager = new TechnicalManager();        technicalManager.setNextHandler(boss); // 设置下一级        technicalManager.handleMessage(demandA);        System.out.println("============================");        technicalManager.handleMessage(demandB);    }}

可以看到在客户端中的重点是设置下一级的处理者,这样多个处理者对象就会形成一条链。运行客户端,结果如下:

需求:加一张露一点点的图

TechnicalManager:小猿我挺你,这个需求不干

============================

需求:加一张露一点点的图

TechnicalManager:事情太严重,需报告上一级

Boss:你们打一架吧,打赢的做决定

从结果可以看到,级别低的请求技术经理自己处理,级别高的传递给了下一级的Boss,这样就形成一条链,而这也是责任链的核心所在。注意,在请求的传递过程中,请求是不会发生变化的。需求不会从“加一张露一点点的图”变成了“加一张露点的图”,这等着boss请到办公室喝茶吧。

三、扩展

责任链+模板方法

回头看看上面的代码,抽象类中定义了几个方法,一个是final修饰的handleMessage,一个是抽象方法report,还有一个是setNextHandler。这刚好是模板方法模式中的三个基本方法,分别是具体方法(抽象类声明并实现,子类不实现)、抽象方法(抽象类声明,子类必须实现)、钩子方法(抽象类声明并实现,子类可扩展)。handleMessage方法加了final修饰,子类不可重写,而handleMessage正是把传递请求工作交给父类Handler,子类不需要处理传递的工作。而report则是抽象方法,子类必须重写该方法,子类处理请求的业务逻辑。setNextHandler是钩子方法,在这里我们并没有实现。

这样结合模板方法模式的好处在哪?首先加了handleMessage方法,把请求的传递判断从子类中剥离出来,让子类在report方法中专心处理请求的业务逻辑,做到了单一职责原则。再者是子类的实现变得简单了,不需要进行传递的判断,非常有利于快速扩展。

责任链模式VS观察者模式

http://www.apkbus.com/blog-830582-77165.html

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3486/viewspace-2812374/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-02

  • 博文量
    91
  • 访问量
    8490