设计模式—— 十六 :责任链模式

  • IWomen(妇女接口):

public interface IWomen {

//获得个人状况

public int getType();

//获得个人请示

public String getRequest();

}

  • Women(妇女实现类):

public class Women implements IWomen{

/** 通过一个int类型的参数来描述妇女的个人状况 * 1–未出嫁 * 2–出嫁 * 3–夫死 */

private int type = 0;

// 妇女的请示

private String request = “”;

// 构造函数传递过来请求

public Women(int _type, String _request) {

this.type = _type;

this.request = _request;

}

// 获得自己的状况

public int getType() {

return this.type;

}

// 获得妇女的请求

public String getRequest() {

return this.request;

}

}

  • IHandler(有处理权的人员接口):

public interface IHandler {

//一个女性(女儿、妻子或者母亲)要求逛街,你要处理这个请求

public void HandleMessage(IWomen women);

}

  • 实现类:有处理权的人对妇女的请求进行处理,分别有三个实现类,在女儿没有出嫁之前父亲是有决定权的;在女性出嫁后,丈夫有决定权;在女性丧偶后,对母亲提出的请求儿子有决定权;

public class Father implements IHandler {

// 未出嫁的女儿来请示父亲

public void HandleMessage(IWomen women) {

System.out.println(“女儿的请示是:” + women.getRequest());

System.out.println(“父亲的答复是:同意”);

}

}

public class Husband implements IHandler {

// 妻子向丈夫请示

public void HandleMessage(IWomen women) {

System.out.println(“妻子的请示是:” + women.getRequest());

System.out.println(“丈夫的答复是:同意”);

}

}

public class Son implements IHandler {

// 母亲向儿子请示

public void HandleMessage(IWomen women) {

System.out.println(“母亲的请示是:” + women.getRequest());

System.out.println(“儿子的答复是:同意”);

}

}

  • 场景类:

public class Client {

public static void main(String[] args) {

// 随机挑选几个女性

Random rand = new Random();

ArrayList arrayList = new ArrayList();

for (int i = 0; i < 5; i++) {

arrayList.add(new Women(rand.nextInt(4), “看戏”));

}

// 定义三个请示对象

IHandler father = new Father();

IHandler husband = new Husband();

IHandler son = new Son();

for (IWomen women : arrayList) {

if (women.getType() == 1) {

// 未结婚少女,请示父亲

System.out.println(“\n--------女儿向父亲请示-------”);

father.HandleMessage(women);

} else if (women.getType() == 2) {

// 已婚少妇,请示丈夫

System.out.println(“\n--------妻子向丈夫请示-------”);

husband.HandleMessage(women);

} else if (women.getType() == 3) {

// 母亲请示儿子

System.out.println(“\n--------母亲向儿子请示-------”);

son.HandleMessage(women);

} else {

// 暂时什么也不做

}

}

}

}

首先是通过随机方法产生了5个古代妇女的对象,然后看她们是如何就看戏这件事去请示的,运行结果如下:

在这里插入图片描述

OK,业务已经实现了,但是明显这个业务实现是存在问题的。

● 职责界定不清晰

对女儿提出的请示,应该在父亲类中做出决定,父亲有责任、有义务处理女儿的请示, 因此Father类应该是知道女儿的请求自己处理,而不是在Client类中进行组装出来,也就是说原本应该是父亲这个类做的事情抛给了其他类进行处理。

● 代码臃肿

我们在Client类中写了if…else的判断条件,而且能随着能处理该类型的请示人员越多,if…else的判断就越多。

● 耦合过重

这是什么意思呢,我们要根据Women的type来决定使用IHandler的那个实现类来处理请 求。有一个问题是:如果IHandler的实现类继续扩展怎么办?如果修改Client类,那就违背了开闭原则。

● 异常情况欠考虑

妻子只能向丈夫请示吗?如果妻子(比如一个现代女性穿越到古代了,不懂什么“三从四德”)向自己的父亲请示了,父亲应该做何处理?我们的程序上可没有体现出来,逻辑失败了!

引入责任链模式


针对上面的问题,这时候就该考虑引入责任链模式了。

可以抽象成这样一个结构,女性的请求先发送到父亲类,父亲类一看是自己要处理的,就 作出回应处理,如果女儿已经出嫁了,那就要把这个请求转发到女婿来处理,那女婿一旦去天国报道了,那就由儿子来处理这个请求,类似于如图16-3所示的顺序处理图:

图16-3:女性请示的顺序处理图

在这里插入图片描述

父亲、丈夫、儿子每个节点有两个选择:要么承担责任,做出回应;要么把请求转发到后序环节。

根据责任链模式,修改后的类图如下:

图16-4:使用责任链模式后的女子“三从”类图

在这里插入图片描述

实现如下:

  • 改造后的Handler类:

public abstract class Handler {

public final static int FATHER_LEVEL_REQUEST = 1;

public final static int HUSBAND_LEVEL_REQUEST = 2;

public final static int SON_LEVEL_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”);

}

}

/** 如果不属于你处理的请求,你应该让她找下一个环节的人,如女儿出嫁了, * 还向父亲请示是否可以逛街,那父亲就应该告诉女儿,应该找丈夫请示 */

public void setNext(Handler _handler) {

this.nextHandler = _handler;

}

//有请示那当然要回应

protected abstract void response(IWomen women);

}

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

三个实现类如下:三个实现类分别处理不同等级的请求

  • 父亲类:

public class Father extends Handler {

// 父亲只处理女儿的请求

public Father() {

super(Handler.FATHER_LEVEL_REQUEST);

}

// 父亲的答复

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.HUSBAND_LEVEL_REQUEST);

}

//丈夫请示的答复

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_LEVEL_REQUEST);

}

// 儿子的答复

protected void response(IWomen women) {

System.out.println(“--------母亲向儿子请示-------”);

System.out.println(women.getRequest());

System.out.println(“儿子的答复是:同意\n”);

}

}

  • Women类的接口没有任何变化

  • 实现类稍微有些变化:为了展示结果清晰一点,输出请求的来源

public class Women implements IWomen {

/**

  • 通过一个int类型的参数来描述妇女的个人状况 1–未出嫁 * 2–出嫁 * 3–夫死

*/

private int type = 0;

// 妇女的请示

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;

}

}

// 获得自己的状况

public int getType() {

return this.type;

}

// 获得妇女的请求

public String getRequest() {

return this.request;

}

}

  • 场景类:

public class Client {

public static void main(String[] args) {

// 随机挑选几个女性

Random rand = new Random();

ArrayList arrayList = new ArrayList();

for (int i = 0; i < 5; i++) {

arrayList.add(new Women(rand.nextInt(4), “我要看戏”));

}

// 定义三个请示对象

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);

}

}

}

最后希望可以帮助到大家!

千千万万要记得:多刷题!!多刷题!!

之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!

篇幅有限,以下只能截图分享部分的资源!!

(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)

image

(2)刷的算法题(还有左神的算法笔记)

image

(3)面经+真题解析+对应的相关笔记(很全面)

image

(4)视频学习(部分)

ps:当你觉得学不进或者累了的时候,视频是个不错的选择

在这里,最后只一句话:祝大家offer拿到手软!!
);

}

// 定义三个请示对象

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);

}

}

}

最后希望可以帮助到大家!

千千万万要记得:多刷题!!多刷题!!

之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!

篇幅有限,以下只能截图分享部分的资源!!

(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)

[外链图片转存中…(img-aBAvFNLL-1720130110115)]

(2)刷的算法题(还有左神的算法笔记)

[外链图片转存中…(img-fMQEWOgq-1720130110116)]

(3)面经+真题解析+对应的相关笔记(很全面)

[外链图片转存中…(img-yaOaViMG-1720130110117)]

(4)视频学习(部分)

ps:当你觉得学不进或者累了的时候,视频是个不错的选择

在这里,最后只一句话:祝大家offer拿到手软!!

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值