去年参加校招要到长沙来,这个对于我来说不是特别喜欢(但又必须的来,谁叫咱不是985、211的娃呢),但是对于某些人来说就是福音了。大四还有课,而且学校抓的比较严,所以对于那些想翘课的人来说这个是最好不过的理由了—去参加校招了。所以咱学校规定所以去参加校招的必须要请假,且必须要有相关人员的签字,三天一下,辅导员签字、三到七天系主任签字,一个星期以上院长签字,更多?校长(不知道能不能找到校长呢?反正我是没见校长几面),出了这样的政策确实上课情况好多了!对于这中将请求一级一级地往上传递直到处理请求为止的设计模式就是职责链模式。

上图将学生、辅导员、系主任、院长、校长组成了一个简单的链。在这个链上,学生是申请者,其余的都是请求处理者。职责链可以将请求的处理者组织成一条链,并且将请求沿着链传递,如果某个请求处理者能够处理请求则处理,否则将该请求交由上级处理。

职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了,这就是职责链的设计动机。

一、模式定义

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,这就是职责链模式。

在职责链模式中最关键的一点就是客户提交请求后,请求沿着链往下传递直到有一个处理者处理它,在这里客户无需关心它的请求是哪个处理者来处理,反正总有一个处理者会处理它的请求。

在这里客户端和处理者都没有对方明确的信息,同时处理者也不知道职责链中的结构。所以职责链可以简化对象的相互连接,他们只需要保存一个指向其后续者的引用,而不需要保存所有候选者的引用。

在职责链模式中我们可以随时随地的增加或者更改一个处理者,甚至可以更改处理者的顺序,增加了系统的灵活性。处理灵活性是增加了,但是有时候可能会导致一个请求无论如何也得不到处理,它会被放置在链末端,这个既是职责链的优点也是缺点。

二、模式结构

下图是职责链模式的UML结构图:

从上面可以看出职责链包含三个角色:

      Handler: 抽象处理者。定义了一个处理请求的方法。所有的处理者都必须实现该抽象类。 
      ConcreteHandler: 具体处理者。处理它所负责的请求,同时也可以访问它的后继者。如果它能够处理该请求则处理,否则将请求传递到它的后继者。 
      Client: 客户类。

下面是最典型的具体处理者类。

public class ConcreteHandler extends Handler
{
public void handleRequest(String request)
{
if(请求request满足条件)
{
...... //处理请求;
}
else
{
this.successor.handleRequest(request); //转发请求
}
}
}

三、模式的实现

我们将使用开头那个请假的实例。请假:3天以下辅导员签字、3到5天系主任签字、6到10天院长签字、11-15天校长签字、15天以上不允签字。

首先是请假条:LeaveNode.java

public class LeaveNode {
/** 请假天数 **/
private int number; /** 请假人 **/
private String person; public LeaveNode(String person,int number){
this.person = person;
this.number = number;
} public int getNumber() {
return number;
} public void setNumber(int number) {
this.number = number;
} public String getPerson() {
return person;
} public void setPerson(String person) {
this.person = person;
}
}

抽象处理者:Leader.java

public abstract class Leader {
/** 姓名 **/
public String name; /** 后继者 **/
protected Leader successor; public Leader(String name){
this.name = name;
} public void setSuccessor(Leader successor) {
this.successor = successor;
} public abstract void handleRequest(LeaveNode LeaveNode);
}

四个具体处理者:辅导员:Instructor.java

public class Instructor extends Leader{

    public Instructor(String name){
super(name);
} public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 3){ //小于3天辅导员审批
System.out.println("辅导员" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给系主任
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
} }

系主任: DepartmentHead.java

public class DepartmentHead extends Leader{

    public DepartmentHead(String name) {
super(name);
} public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 7){ //小于7天系主任审批
System.out.println("系主任" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给院长
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
}
}

院长:Dean.java

public class Dean extends Leader{

    public Dean(String name) {
super(name);
} public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 10){ //小于10天院长审批
System.out.println("院长" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给校长
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
} }

校长:President.java

public class President extends Leader{

    public President(String name) {
super(name);
} public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 15){ //小于15天校长长审批
System.out.println("校长" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则不允批准
System.out.println("请假天天超过15天,不批准...");
}
} }

客户端:Client.java

public class Client {
public static void main(String[] args) {
Leader instructor = new Instructor("陈毅"); //辅导员
Leader departmentHead = new DepartmentHead("王明"); //系主任
Leader dean = new Dean("张强"); //院长
Leader president = new President("王晗"); //校长 instructor.setSuccessor(departmentHead); //辅导员的后续者是系主任
departmentHead.setSuccessor(dean); //系主任的后续者是院长
dean.setSuccessor(president); //院长的后续者是校长 //请假3天的请假条
LeaveNode leaveNode1 = new LeaveNode("张三", 3);
instructor.handleRequest(leaveNode1); //请假9天的请假条
LeaveNode leaveNode2 = new LeaveNode("李四", 9);
instructor.handleRequest(leaveNode2); //请假15天的请假条
LeaveNode leaveNode3 = new LeaveNode("王五", 15);
instructor.handleRequest(leaveNode3); //请假20天的请假条
LeaveNode leaveNode4 = new LeaveNode("赵六", 20);
instructor.handleRequest(leaveNode4);
}
}

运行结果:

辅导员陈毅审批张三同学的请假条,请假天数为3天。
院长张强审批李四同学的请假条,请假天数为9天。
校长王晗审批王五同学的请假条,请假天数为15天。
请假天天超过15天,不批准...

  

四、模式的优缺点

优点

      1、降低耦合度。它将请求的发送者和接受者解耦。

      2、简化了对象。使得对象不需要知道链的结构。

      3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。

      4、增加新的请求处理类很方便。

缺点

1、不能保证请求一定被接收。

2、系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。

3、可能不容易观察运行时的特征,有碍于除错。

五、模式适用场景

      1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

      2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

      3、可动态指定一组对象处理请求。

六、总结

       1、职责链模式将请求的发送者和接受者解耦了。客户端不需要知道请求处理者的明确信息,甚至不需要知道链的结构,它只需要将请求进行发送即可。

      2、职责链模式能够非常方便的动态增加新职责或者删除职责。

      3、客户端发送的请求可能会得不到处理。

      4、处理者不需要知道链的结构,只需要明白他的后续者是谁就可以了。这样就简化了系统中的对象。

设计模式:职责链模式(Chain of Responsibility)的更多相关文章

  1. C#设计模式——职责链模式(Chain Of Responsibility Pattern)

    一.概述 在软件开发中,某一个对象的请求可能会被多个对象处理,但每次最多只有一个对象处理该请求,对这类问题如果显示指定请求的处理对象,那么势必会造成请求与处理的紧耦合,为了将请求与处理解耦,我们可以使 ...

  2. atitit.设计模式(1)--—职责链模式(chain of responsibility)最佳实践O7 日期转换

    atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 可以选择的模式: 表格模式,责任链模式 1 3 ...

  3. 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)

     设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就 ...

  4. 责任链模式 职责链模式 Chain of Responsibility Pattern 行为型 设计模式(十七)

    责任链模式(Chain of Responsibility Pattern) 职责链模式 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这些对象连接成一条链,并沿着这 ...

  5. 设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)

     设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就 ...

  6. 职责链模式(Chain of Responsibility)(对象行为型)

    1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就推卸给另外个一个部门(对象).至于到底谁来解决这个问题呢?政府部门就是为了可以避免屁民的请求与 ...

  7. 设计模式之职责链模式(Chain of Responsibility)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  8. 行为型设计模式之职责链模式(Chain of Responsibility)

    结构 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 适用性 有多个的对象可以处理一个请求,哪个 ...

  9. 重温设计模式(三)——职责链模式(chain of responsibility)

    一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所 ...

随机推荐

  1. 日照学习提高班day4测试

    A 思路: 一看到这个题,他不仅要求输出字典序最小的串,还要满足两两不重复,所以我们可以先输出ababab...什么的,最后缀上要求的k-2种字母 坑点: 当然这样想是不完全的!该题是拥有许多特殊情况 ...

  2. BZOJ 2651 城市改建 树形DP+模拟?

    题意 给一颗树,删除一条边再加一条边,使它仍为一颗树且任意两点间的距离的最大值最小. 题目数据范围描述有问题,n为1或重建不能使任意两点距离最大值变小,可以输出任意答案. 分析 删除一条边后会使它变成 ...

  3. easyUI datagrid中checkbox选中事件以及行点击事件,翻页之后还可以选中

    DataGrid其中与选择,勾选相关 DataGrid属性:singleSelect boolean 如果为true,则只允许选择一行. false ctrlSelect boolean 在启用多行选 ...

  4. vue-cli3中axios如何跨域请求以及axios封装

    1. vue.config.js中配置如下 module.exports = { // 选项... // devtool: 'eval-source-map',//开发调试 devServer: { ...

  5. 26.Python三目运算符(三元运算符)用法详解

    Python 可通过 if 语句来实现三目运算符的功能,因此可以近似地把这种 if 语句当成三目运算符.作为三目运算符的 if 语句的语法格式如下: True_statements if expres ...

  6. 2018-2019-2 网络对抗技术 20165205 Exp8 Web基础

    2018-2019-2 网络对抗技术 20165205 Exp8 Web基础 1.原理与实践说明 1.1实践内容 Web前段HTML:能正常安装.启停Apache.理解HTML,理解表单,理解GET与 ...

  7. docker基础知识普及(一)

    背景 这篇内容是之前给部门同事培训时写的文档,旨在传达一些docker相关概念,有个基本印象,当然,以下内容都来自网络,我只是个搬运工.具体操作在下篇文章中 一.什么是docker? 1. Docke ...

  8. 读取天气信息,并通过QQ邮箱发送至指定邮箱

    from email.mime.text import MIMEText from email.header import Header from smtplib import SMTP_SSL im ...

  9. Python全栈开发第5天作业

    作业一:1) 将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) 2) 将用户信息数据库文件和用户密码数据库文件纵向合并为一个文件/2.txt(追加) 3) 将/1.txt. ...

  10. anroid学习笔记(1)

    大概是2个月前,报名了慕课的android就业班课程. 算是补全了当初博客分类的最初设计. 安卓和前端比较: 1,java在安卓开发中的作用,现在我的认识是和JavaScript在前端web开发中有很 ...