热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《设计模式之禅》学习之“责任链模式”

本章一开始举了中国古代对妇女制定的“三从四德”的道德规范,形象地将女性在“未嫁->出嫁->丧父”三个不同的状态下请示出门逛街获得的处理,未嫁的时候,请示父亲;出嫁了,请示丈夫

本章一开始举了中国古代对妇女制定的 “三从四德” 的道德规范,形象地将女性在 “未嫁-> 出嫁 -> 丧父” 三个不同的状态下请示出门逛街获得的处理,未嫁的时候,请示父亲;出嫁了,请示丈夫;丈夫去世了,请示儿子。责任链就是:父亲 -> 丈夫 -> 儿子。如果出嫁了,请示父亲,会得到什么结果?答案是:父亲告诉他,你该去请示你的丈夫。读完还是蛮形象的。
其实,作者给我们阐述了这么一个场景:一个请求到来的时候,请求方并不知道也不必知道谁去处理请求,责任链也不必关心谁发出的请求。请求来了,从第一个处理者开始,如果属于这一层,就处理。不属于?分发到下一个节点。下一个不能处理怎么办?再下一个。寻找处理者就是遍历链表节点的过程。
为什么这么做?这样做,就避免了请求和处理耦合在一起,代码也简洁了很多。
Talk is cheap, show me the code.
先创建一个女性接口:

public interface IWomen {

// 获得个人状态.
public int getType();

// 获得个人请示
public String getRequest();
}

创建一个古代妇女:

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

/**
* 获取自己的状态.
*
* @return
*/
public int getType() {
return this.type;
}

/**
* 获取妇女的请求.
*
* @return
*/
public String getRequest() {
return this.request;
}
}

有处理权的人员接口:

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

/**
* 处理女性的请求.
*
* @param women
*/
public final void HandleMessage(IWomen women) {
if (women.getType() == this.level) {
this.response(women);
} else {
if (null != this.nextHandler) {
this.nextHandler.HandleMessage(women);
} else {
// 没有后续的处理人了.
System.out.println("\n-------没有地方请示了,按不同意处理-------\n");
}
}
}

/**
* 如果不属于该类处理的请求,应该将其设置到下一个需要请求的环节.
*
* @param handler
*/
public void setNextHandler(Handler handler) {
this.nextHandler = handler;
}

/**
* 有请求肯定要有回应
*
* @param women
*/
protected abstract void response(IWomen women);
}

父亲类:

public class Father extends Handler {

public Father() {
super(Handler.FATHER_LEVEL_REQUEST);
}

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

丈夫类:

public class Husband extends Handler {

public Husband() {
super(Handler.HUSBAND_LEVEL_REQUEST);
}

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

儿子类:

public class Son extends Handler {

public Son() {
super(Handler.SON_LEVEL_REQUEST);
}

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

场景类:

public class Client {
public static void main(String[] args) {
Random random = new Random();
ArrayList arrayList = new ArrayList();

for (int i = 0; i <5; i++) {
arrayList.add(new Women(random.nextInt(4), "我要去逛街"));
}

// 定义三个请求对象
Father father = new Father();
Husband husband = new Husband();
Son son = new Son();

father.setNextHandler(husband);
husband.setNextHandler(son);

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

运行结果:

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

-------妻子向丈夫请示-------
妻子的请求是: 我要去逛街
丈夫的答复是: 同意
-------母亲向儿子请示-------
母亲的请求是: 我要去逛街
儿子的答复是: 同意


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

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

在抽象类 Handler 中,我们设置了级别 level 的参数用来标示子类的等级;定义了 nextHandler 来制定当前节点的下一个处理节点。这样,每个子类在生成实例对象的时候,通过指定下一个节点,就可以生成责任链了。
责任链模式的重点是在“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果。其优点就是将请求和处理分开来了。请求者不需要知道谁将处理这个请求,处理者也不要知道谁发起了这个请求。两者解耦,提高了系统的灵活性。


推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
author-avatar
zhou
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有