职场小白初涉设计模式之责任链模式

最近,接到一个需求,在数据计算之前,根据需求的具体内容对数据进行过滤,保留下需要计算的那部分。

对于职场小白没经验的我来说,拿到需求,在确定于什么位置过滤数据以后,就开始义无反顾地码代码!!

怎么码呢?当然是建立需要过滤的接口及实现类,然后在里面进行过滤的具体操作。

由于过滤数据的两部分是对同一内容进行操作,于是在计算数据之前,

嗯,调用第一个实现类方法得到要过滤的内容,循环过滤数据,过滤第一部分;

再来调用第二个实现类方法得到要过滤的内容,循环过滤数据,过滤第二部分。

到这里,需求的功能性基本上算是完成了。但这样的方式好么?!

如果再来第三个第四个相同的过滤操作呢?!接着如上循环么?!

明眼人都能看出来这种方式存在了很大的代码冗余,效率并不是很高,

且后一部分的过滤在前一部分的过滤之后,耦合太紧,以后再看到的话肯定头疼。

于是,在同事亦师父的林哥的耐心指导下,开始以责任链的形式来优化这部分代码。

一、对责任链的理解

责任链模式(Chain of Responsibility Pattern)即为请求创建一个接收者对象的链,给与请求类型,将请求发送者与接收者之间进行解耦。请求的处理被每一个接收者进行接收并处理,如果能处理则按照接收者的既定规则处理,然后在该责任链上层层传递。也可以在每一个接收者中持有下一个接收者的引用,如果自己不能处理,则传给下一个进行处理。

请求由责任链上的每个接收者进行处理,因此,客户在传入请求之后,不需要关心接收者的处理细节以及如何传递的,这就实现了请求的发送者和请求接收者之间进行了解耦。

(一)大致实现

1、首先创建一个Handler类,其包含对请求进行处理的方法HandlerRequest();

2、对于不同的请求处理方式,创建其相应的接收者类,并继承并重写Handler父类中的HandlerRequest()方法,以自己的方式进行实现;

3、对于接收者类的传递上,是在每个接收者类中持有下一接收者的引用,这样处理不了的请求就传递给下一个接收者进行处理。

 (二)优缺点

优点:1、首先是责任的分担。每个类都只需承担自己的责任进行处理,如果不能处理就传递给下一个对象,明确各类的职责范围,符合类的最小封装原则。

    2、可以根据实际场景的需要自由组合处理流程。如需变更,只需要重新分配该对象链即可。

    3、类与类之间以松耦合的方式来传递请求,降低了耦合。

缺点: 由于请求在各个接收者之间进行传递,而每个接收者处理的方式不同,可能会影响处理速度。

(三)应用场景

责任链既然叫链,即是用于链式处理的场景中,使得工作流程化、处理过程流程化。

例如:1、Web开发过程中对请求的各种filter处理,如请求处理和过滤、对Encoding的处理、获取客户端IP地址、获取客户证书等。(这个是大家最熟悉的部分)

   2、JS的冒泡事件。(这个本人没太过深入研究,看了下,大致意思是某事件被触发,如鼠标点击了一下按钮,那么该事件会在该元素的所有祖先当中被触发,即自下而上的。)

     3、多个对象处理一个请求时。

二、我是如何来实现责任链的

说完了个人对责任链的理解,接下来就通过一个简单的例子来讲解本人是如何实现责任链的。

1、定义一个IRule接口,制定请求处理方法的规则,各接收者都将实现该接口并重写该方法;

1 public interface IRule {
2
3     /**
4      * 对字符串进行处理
5      * @return
6      */
7     Object handler();
8 }

2、定义一个RuleChain类,主要包含两部分,一部分是能接收传递进来的请求对象,一部分是对请求进行处理。

  这两个部分保证了在传递请求继续不同处理时,能将接收者加入到责任链中形成链式结构,后续在增加新的相关接收处理者对象时只需实现自身处理并加入到责任链中即可;同时每一个接收者都重写了该责任链的处理方法,这样在进行责任链处理时,如果是对相同数据进行处理,只需要一个循环来进行验证即可,避免了代码的冗余。

 1 public class RuleChain {
 2
 3     /**
 4      *  装载各个接收者对象的链
 5      */
 6     private List<IRule> chain;
 7
 8     public RuleChain() {
 9         chain = new ArrayList<>();
10     }
11
12     public RuleChain addRule(IRule rule) {
13         chain.add(rule);
14         return this;
15     }
16
17     /**
18      * 各个接收者自行处理数据
19      */
20     public void handler(StringObj stringObj){
21         for (IRule rule : chain){
22             stringObj = rule.handler();
23         }
24     }
25 }

3、接收者的实现方法

  这部分主要是实现RuleChain接口并根据自身情况重写其请求处理方法。这样RuleChain可以统一地进行请求处理,然后轮到该接收者时,就会调用其重写的请求处理方法进行处理。

 1 public class ConcreteHandlerA implements IRule {
 2
 3     private StringObj str;
 4
 5     public ConcreteHandlerA(StringObj str){
 6         this.str = str;
 7     }
 8
 9     /**
10      * 该方法在字符串上上添加“ConcreteHandlerA”
11      */
12     @Override
13     public StringObj handler() {
14         String string=str.getStr()+"ConcreteHandlerA接收者开始处理,";
15         str.setStr(string);
16         return  str;
17     }
18 }

 1 public class ConcreteHandlerB implements IRule{
 2
 3     private StringObj str;
 4
 5     public ConcreteHandlerB(StringObj str){
 6         this.str = str;
 7     }
 8
 9     /**
10      * 判断前面字符串的长度,
11      * @return
12      */
13     @Override
14     public StringObj handler() {
15         String end = "ConcreteHandlerB处理完毕,责任链结束";
16         String string = "";
17         if (str.getStr().length() > 10) {
18             string=str.getStr()+ "前面字符串长度为"+str.getStr().length()+","+end;
19         }else{
20             string=str.getStr()+ "前面字符串长度不足10,只有"+str.getStr().length()+","+end;
21         }
22         str.setStr(string);
23         return  str;
24     }
25 }

4、Main方法验证实现及输出结果

 1 public class Main {
 2
 3     public static void main(String[] args) {
 4         StringObj stringObj = new StringObj("责任链开始,");
 5         RuleChain chain = new RuleChain().addRule(new ConcreteHandlerA(stringObj)).addRule(new ConcreteHandlerB(stringObj));
 6         chain.handler(stringObj);
 7         System.out.println(stringObj.getStr());
 8     }
 9 }
10
11 ==================================================
12 责任链开始,ConcreteHandlerA接收者开始处理,前面字符串长度为30,ConcreteHandlerB处理完毕,责任链结束

三、责任链实现的设计模式六大原则体现

如上所示则为一个简答的责任链的大致实现过程。

1、通过上面的例子我们可以看到,每一个类只进行自己的那部分处理方式,符合设计模式的单一职责原则,实现了高内聚低耦合的方针;

2、在Main函数中的main方法中,对于RuleChain来说,我们只需在后续增加各个处理模块即可,然后在每个处理模块中实现自定义处理。在对各个处理模块的增加来说,我们只需实现IRule接口,并重写其handler方法,即可满足需求。这符合设计模式的开闭原则,即对扩展开放,对修改关闭

3、接收者的各个类都统一实现了专门的IRule接口,而不会去实现不必要的其他接口,符合接口隔离原则

4、接收者的handler方法都实现了IRule中的方法,IRule负责抽象方法,而具体的实现细节都放在了各个接收者内部进行处理,符合依赖倒置原则

5、我们从上述例子中可以看到,接收者的类与类之间是不存在耦合的,其链接都是依靠RuleChain来进行的,因此符合迪米特法则,类与类之间的耦合性降低。

6、里氏替换原则在这里暂时不是很明显。

四、其他

大致先说到这里,后续再进行补充。

如有描述不足之处,请指教!

原文地址:https://www.cnblogs.com/nalanshawn/p/9574763.html

时间: 2024-07-30 07:14:30

职场小白初涉设计模式之责任链模式的相关文章

设计模式之责任链模式20170717

行为型设计模式之责任链模式: 一.含义 责任链模式的核心在"链"上,"链"是由多个处理者(对象)组成的,由这条链传递请求,直到有对象处理它为止(在链中决定谁来处理这个请求),并返回相应的结果 二.代码说明 1.主要有两个角色 1)处理者 它能够对请求做出处理(请求得到处理则直接返回,否则传到下一个处理者),设置下一个处理者(这两个操作可以抽象出来), 同时每个处理者都有一个相应的处理级别,以及具体的处理操作(父类实现请求传递,子类实现请求处理) 2)被处理者(请求者

设计模式之责任链模式--- Pattern chain-of-responsibility

模式的定义 责任链模式定义如下: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it. 使多个对象都有机会处理请求,从而避免请求的发送

设计模式_责任链模式

定义 Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求.从而避免了请求的发送者和接受者之间的耦合关系.

Java设计模式之责任链模式、职责链模式

本文继续介绍23种设计模式系列之职责链模式. 什么是链 1.链是一系列节点的集合. 2..链的各节点可灵活拆分再重组. 职责链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止. 角色 抽象处理者角色(Handler):定义出一个处理请求的接口.如果需要,接口可以定义 出一个方法以设定和返回对下家的引用.这个角色通常由一个Java抽象类或者Java接口实现. 具体处理者角色(ConcreteHan

C#设计模式:责任链模式

设计模式是面向对象编程的基础,是用于指导程序设计.在实际项目开发过程中,并不是一味将设计模式进行套用,也不是功能设计时大量引入设计模式.应该根据具体需求和要求应用适合的设计模式.设计模式是一个老话题了,因为最近在设计“网关API”组件(后续介绍),采用“责任链设计模式”进行设计,所以先进行回顾记录.  一.责任链模式介绍 责任链模式是指一个处理需要涉及多个过程或者角色参与处理,并基于某个约定组成一个链,每个过程或者角色拥有各自职责进行处理.责任链模式有效组织一个过程处理,同时子过程之间职责明确.

【GOF23设计模式】责任链模式

来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_责任链模式.公文审批.供应链系统的采购审批.异常链.过滤器和拦截器调用过程 1 package com.test.chainOfResp; 2 /** 3 * 封装请假的基本信息 4 */ 5 public class LeaveRequest { 6 private String empName; 7 private int leaveDays; 8 private String reason; 9 10 publi

Head First设计模式之责任链模式

一.定义 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止. 主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了. 何时使用:在处理消息的时候以过滤很多道. 如何解决:拦截的类都实现统一接口. 二.结构 从责任链模式的定义可以发现,责任链模式涉及的对象只有处理者角色,但由于有多个处理者,它们具有共同的处理请求的

23种设计模式之责任链模式(Chain of Responsibility)

责任链模式是一种对象的行为型模式,避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止.责任链模式不保证每个请求都被接受,由于一个请求没有明确的接收者,那么就不能保证它一定会被处理. 优点: 1)降低了耦合度. 2)增加向对象指定责任的灵活性. 3)由于在一个类中产生的事件可以被发送到组成中的其它类处理器上,类的集合可以作为一个整体. 使用场景: 1)多个对象可以处理一个请求,而其处理器却是未知的. 2)想要在不指定确

五分钟一个设计模式之责任链模式

五分钟一个设计模式,用最简单的方法来描述设计模式.查看更多设计模式,请点击五分钟一个设计模式系列 http://blog.csdn.net/daguanjia11/article/category/3259443 请假流程 假设现在一个公司的请假流程如下:一天及以下由小组组长审批,一天以上三天以下由经理审批,三天以上七天以下由老板审批,七天以上直接劝退. 如果每次请假时都很长的if-else-来判断该去找谁请假,很不容易扩展,我们使用责任链模式来实现. 首先,是一个抽象的父类 public ab