设计模式篇—责任链模式详解
- 格式:pdf
- 大小:465.24 KB
- 文档页数:11
责任链设计模式(过滤器、拦截器)责任链设计模式(Chain of Responsibility)的应⽤有:Java Web中的过滤器链、Struts2中的拦截器栈。
先看⼀个问题:给定⼀个字符串“被就业了:),敏感信息,<script>”,对其中的HTML标记和敏感词进⾏过滤或替换。
本⽂主要以该问题设计⽅法的演变来讲解责任链设计模式。
第⼀种设计:没有任何设计模式设计了⼀个MsgProcessor类,完成字符串处理的主要⼯作。
MainClass类是本设计中的测试类。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30public class MainClass {public static void main(String[] args) {//需要被过滤的语句String msg = "被就业了:),敏感信息,<script>"; //实例化处理类MsgProcessor mp = new MsgProcessor(msg); String r = mp.process();System.out.println(r);}}public class MsgProcessor {private String msg;public MsgProcessor(String msg){this.msg = msg;}public String process(){String r = msg;//过滤msg中的HTML标记r = r.replace("<", "<").replace(">", ">");//过滤敏感词r = r.replace("敏感", "").replace("被就业", "就业"); return r;}}第⼆种设计:增加⼀个Filter接⼝在第⼀种设计中,对字符串的所有处理都放在MsgProcessor类中,扩展性极差。
软件工程中的设计模式在软件开发的过程中,设计模式是一种非常重要的概念。
设计模式是指在软件开发中,经过反复使用,被证明是有效的、可重用的经验总结,是程序员在软件开发中总结出来的比较好的实践方法。
设计模式让程序员能够在软件开发中更加灵活、高效地处理问题,提高了软件开发的质量和效率。
设计模式可以分为三种类型:创建型模式、结构型模式和行为型模式。
其中每种模式都有其独特的应用场景和解决方案。
一、创建型模式创建型模式主要解决对象的创建问题,提供了一种系统化的创建对象的方式,使得对象的创建过程更加灵活和高效。
创建型模式包括单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式。
1. 单例模式单例模式是设计模式中最简单的模式之一,它是保证一个类只有一个实例,在全局中的唯一性。
单例模式的优点在于:1. 可以减小系统开销,避免重复创建对象。
2. 增加了灵活性,可以控制对象的生成顺序,实现对象共享等。
3. 可以和工厂模式和代理模式结合使用。
2. 工厂模式工厂模式是一种比较常见的创建型模式,它使用工厂方法来生成对象,而不是在代码中直接使用构造函数来生成对象。
工厂模式可以有多种不同的实现方式,包括简单工厂模式、工厂方法模式和抽象工厂模式。
工厂方法模式的优点在于:1. 解耦客户端和具体的产品类。
2. 扩展性好,可以增加新的产品类。
3. 可以实现多态,提高系统的灵活性。
3. 抽象工厂模式抽象工厂模式是工厂方法模式的拓展,它提供一个工厂接口用于创建一组相关或者相互依赖的对象。
抽象工厂模式的优点在于:1. 解耦客户端和具体的产品类。
2. 扩展性好,可以增加新的产品类。
3. 实现了一系列的产品族,满足客户端的需求。
4. 建造者模式建造者模式是一种用于构建复杂对象的模式,它将对象的构造和表示分离,使得同样的构建过程可以创建不同的表示方式。
建造者模式的优点在于:1. 可以对对象的构建过程进行控制,更加灵活。
2. 可以解决不同构建过程的复杂性,简化代码的编写。
设计模式【15】--从审批流中学习责任链模式已经来到了责任链模式,各位客官听我瞎扯......责任链模式是什么责任链模式是⼀种设计模式。
在责任链模式⾥,很多对象由每⼀个对象对其下家的引⽤⽽连接起来形成⼀条链。
请求在这个链上传递,直到链上的某⼀个对象决定处理此请求。
发出这个请求的客户端并不知道链上的哪⼀个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
(百度百科)责任链模式是⼀种⾏为型设计模式,也就是重点是处理数据,假设我们有⼀份数据,需要经过很多个节点处理,那么就会是以下这个样⼦:⼀个节点处理完之后,交给下⼀个节点,不知道⼤家有没有使⽤过审批流,当我们提完⼀个审批单后,你的leader审批,leader审批通过之后就是总监批,总监后⾯可能是⾼级总监,或者cto,或者hr。
他们在同⼀个链条上,倘若你的leader没有审批完,后⾯的节点是不可能收到信息的。
如果你的leader拒绝了你的申请,那数据也不会到达后⾯的审批节点。
如果你接触过前端,JS 中点击某个 div 的时候会产⽣冒泡事件,也就是点击下⾯的A, A 在B⾥⾯,B在C⾥⾯, A-> B -> C 会依次收到点击事件:再举个例⼦,在 SpringMVC中,我们有时候会定义⼀些拦截器,对请求进⾏预处理,也就是请求过来的时候,会依次经历拦截器,通过拦截器之后才会进⼊我们的处理业务逻辑代码。
之前,在做⼈员管理的时候,有涉及到⼈员离职情况的处理流程,要交接⼯作,解除权限,禁⽤账号等等,这整个处理流程就很适合使⽤责任链来处理。
当然,⾃动处理流程是会出错的,保存每⼀个阶段的状态,针对出错的场景,可以⼿动去从断开责任链的地⽅接着执⾏。
这整个流程的框架就是应⽤了责任链,但是根据实际场景也添加了不少其他的东西。
两点疑问责任链的每⼀个节点是不是⼀定包含下⼀个节点的引⽤?答:不⼀定,要么把所有责任节点放在⼀个list⾥⾯,依次处理;要么每个节点包含下⼀个责任节点的引⽤,责任链到底是不允许中断还是不允许中断?答:两种都可以,不拘泥于细节,可以根据⾃⼰的场景使⽤。
枚举责任链模式全文共四篇示例,供读者参考第一篇示例:责任链模式是一种行为设计模式,它允许一系列对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合。
这种模式中,请求会沿着一个链条传递,直到有一个对象处理它为止。
这种模式可以提供更大的灵活性和降低耦合度。
在责任链模式中,通常会有一个处理请求的接口,每个处理器都会实现这个接口。
当一个请求到来时,它会先传递给第一个处理器,如果第一个处理器没有处理它,那么它会被传递给下一个处理器,直到有一个处理器能够处理这个请求。
枚举责任链模式是责任链模式的一种变体。
在枚举责任链模式中,责任链中的处理器是固定的,而且它们的顺序是事先确定的。
这种模式适用于处理固定数量的请求,并且每个请求都有固定的处理流程。
枚举责任链模式通常通过枚举类型实现,每个枚举值代表一个处理器。
这样可以保证责任链中的处理器是固定的,不会随意增加或删除。
通过枚举类型可以确保责任链中的处理器的执行顺序是固定的。
枚举责任链模式在实际项目中有着广泛的应用。
比如在电商系统中,订单的处理流程是一个典型的责任链模式。
订单在提交后,需要经过一系列处理,比如订单校验、库存检查、支付处理等。
这些处理流程就可以通过枚举责任链模式来实现。
另一个应用场景是在权限控制系统中。
不同的用户可能有不同的权限,而权限控制系统可以通过责任链模式来实现。
每个处理器代表一种权限级别,请求会依次传递给不同的处理器,直到找到一个能够处理该请求的处理器为止。
枚举责任链模式是一种简单而有效的设计模式,它可以帮助我们实现复杂的处理流程,降低组件之间的耦合度,提高系统的灵活性和可维护性。
在实际项目中,我们可以根据具体情况选择是否使用枚举责任链模式来实现系统的功能。
第二篇示例:枚举责任链模式是一种设计模式,它主要用于解决对象之间的关系及其行为的问题。
在这种模式中,每个对象都有一个自己的责任,并对其自己的责任负责。
如果这个对象无法处理这个责任,它将把责任传递给下一个对象,直到责任被处理为止。
责任链模式的应用场景责任链模式是一种行为设计模式,它通过一系列的处理器对象形成一个链,每个处理器都有机会处理请求,直到请求被处理或者到达链的末端。
该模式常用于解耦发送者和接收者,将请求沿着链传递,并动态地决定由哪个处理器来处理请求。
责任链模式的应用场景非常广泛,下面将介绍几个典型的应用场景:1. 请求处理链:在一个系统中,可能存在多个处理器,每个处理器负责不同的处理逻辑。
通过使用责任链模式,可以将这些处理器连接成一个处理链,每个请求按照处理链的顺序依次经过处理器进行处理,直到找到合适的处理器处理请求或者请求被拒绝。
这种模式可以实现请求的动态处理和灵活的扩展,提高系统的可维护性和可扩展性。
2. 日志记录:在日志记录的场景中,可以使用责任链模式来实现不同级别的日志记录。
例如,系统中分为普通日志、警告日志和错误日志三个级别,每个级别对应一个处理器,处理器根据日志级别来决定是否处理该日志,以及如何处理。
这样,请求日志的对象只需要将日志传递给处理链的第一个处理器,而无需关心具体的处理过程,大大简化了代码的编写和维护。
3. 身份认证:在网络应用中,身份认证是一个重要的功能。
责任链模式可以用于实现不同方式的身份认证,例如用户名密码认证、邮箱验证码认证、短信验证码认证等。
每个认证方式都可以由一个处理器来处理,根据请求的方式和内容来判断是否通过认证。
如果一个处理器无法认证通过,则将请求传递给下一个处理器进行处理,直到找到合适的处理器或者认证失败。
4. 资源分配:在资源分配的场景中,可以使用责任链模式来实现资源的动态分配和优化。
例如,一个服务器集群中存在多台服务器,每台服务器负责处理不同类型的请求。
通过使用责任链模式,可以将请求按照类型分发给不同的服务器进行处理,实现负载均衡和资源优化。
5. 异常处理:在系统开发中,异常处理是一个重要的环节。
责任链模式可以用于实现异常的捕获和处理。
可以将异常捕获的逻辑封装在处理器中,当一个异常被抛出时,责任链上的处理器会依次尝试处理该异常,直到找到合适的处理器或者异常无法处理。
行为型设计模式介绍行为型设计模式是指用于解决对象之间交互及职责分配的设计模式,它们主要描述了不同对象之间的通信方式,以及如何控制对象之间的交互流程。
这些模式通过将行为分离到不同的对象中,来实现更好的封装性和可复用性。
在本篇论文中,我们将对行为型设计模式做一个简要的介绍,包括模式的定义、分类以及如何在实际开发中应用它们。
一、定义行为型设计模式是指一系列用于对象之间交互和职责分配的设计模式。
这些模式主要解决对象间的通信方式以及如何控制对象之间的交互流程。
与创建型设计模式和结构型设计模式不同,行为型设计模式更关注对象之间的功能分配,而不是组成对象的方式。
行为型设计模式主要包括以下几种:1、责任链模式:将请求的发送者和接收者解耦,构造成一条链,依次发送请求,直到有一个接收者处理为止。
2、命令模式:将请求封装成对象,使得请求的发送者与请求的接收者之间解耦,并且可以动态地添加或删除请求。
3、迭代器模式:提供一种方法来顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
4、中介者模式:定义一个中介对象来封装一系列对象之间的交互,使得各对象之间不需要直接相互作用,从而降低耦合度。
5、备忘录模式:提供一种方式来捕获对象的内部状态,并可以在需要的时候恢复对象到之前的状态。
6、观察者模式:对象之间的一种一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并且自动更新。
7、状态模式:允许一个对象在其内部状态改变时改变其行为,从而使对象看起来似乎修改了其所属的类。
8、策略模式:定义了一系列算法,并将每个算法都封装起来,使得它们可以互相替换。
9、模板方法模式:定义了一个算法框架,由具体子类实现其中的某些步骤,可以提供一个保护性的具体方法,以约束它的子类必须遵循的规则。
10、访问者模式:在不改变对象的前提下,定义作用于对象某些元素的新操作。
二、分类行为型设计模式可以分为两类:类行为型模式和对象行为型模式。
责任链模式(ChainofResponsibilityPattern)责任链模式是一种对象的行为模式。
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
请求在这个链上传递,直到链上的某一个对象决定处理此请求。
发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使系统可以在不影响客户端的情况下动态的重新组织链和分配责任。
一、责任链模式的结构1、责任链模式涉及的角色抽象处理者角色(Handler):定义出一个处理请求的接口。
如果需要,接口可以定义出一个方法,以设定和返回下家的引用。
这个角色通常由一个Java抽象类或Java接口实现。
图中的聚合关系给出了具体子类对下家的引用,抽象方法handlerRequest()规范了子类处理请求的操作。
具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。
由于处理者持有下家引用,因此,如果需要,具体处理者可以访问下家。
抽象处理者角色public abstract class Handler{protected Handler successor;//定义下家的引用public abstract void handleRequest();//处理方法,调用此方法处理请求public void setSuccessor(Handler successor)//赋值方法,调用此方法设置下家{this.successor = successor;}public Handler getSuccessor()//取值方法,得到下家对象{return successor;}}具体处理者角色,如果有下家,就将请求传给下家,否则就处理请求public class ConcreteHandler extends Handler{public void handleRequest(){if (getSuccessor() != null){System.out.println("The request is passed to " + getSuccessor());getSuccessor().handleRequest();}else{System.out.println("The request is handled here.");}}}客户端角色public class Client{static private Handler handler1, handler2;public static void main(String[] args){handler1 = new ConcreteHandler();handler2 = new ConcreteHandler();handler1.setSuccessor(handler2);handler1.handleRequest();}}客户端创建了2个处理者对象,并指定第一个处理者对象的下家是第2个处理者对象,而第2个处理者对象没有下家。
⾏为设计模式⾏为设计模式包括:观察者模式、责任链模式。
1、观察者模式(Observer)观察者模式允许你定义⼀种订阅机制,可在对象状态改变或事件发⽣时通知多个“观察” 该对象的其他对象。
这种模式有时⼜称作发布-订阅模式、模型-视图模式,⽐如顾客对商店⾥的苹果很感兴趣,他会每天到店⾥查看有没有优惠活动,这样其实很浪费时间,这种情况就可以使⽤观察者模式:对苹果感兴趣的顾客作为观察者来向商店订阅苹果的活动消息,当商店的苹果搞活动的时候就通知所有订阅的顾客,顾客⾃⾏处理该通知。
//抽象观察者interface Observer {void response(); //订阅的事件发⽣,进⾏反应}//具体观察者class ConcreteObserver implements Observer {public void response() {System.out.println("观察者作出反应!");}}class Subject{protected List<Observer> observers = new ArrayList<Observer>();public void add(Observer observer) //增加观察者{observers.add(observer);}public void remove(Observer observer) //删除观察者{observers.remove(observer);}public void notifyObserver() //通知所有观察者{for (Observer obs : observers){obs.response();}}}View Code2、责任链模式责任链模式允许你将请求沿着处理者链进⾏发送,处理者收到请求后均可对请求进⾏处理,或将其传递给链上的下个处理者。
⽐如开发⼀个⽹站系统,要求访问者为⼤陆⼈且为认证⽤户,⼀开始我们直接在代码⾥添加相关的判断处理,后来⼜要添加过滤来⾃同⼀ IP 地址的重复错误请求,后来⼜有⼈提议你可以对包含同样数据的重复请求返回缓存中的结果,你⼜要增加⼀个检查步骤。
面向对象设计的23个设计模式详解面向对象设计是一种广泛应用于软件开发的思想,其核心在于将数据和操作封装在一起形成对象,并通过各种方式进行交互和组合,从而实现复杂的功能。
在这一过程中,设计模式起到了非常重要的作用,可以有效地提高代码的可读性、可维护性和可扩展性。
本文将对23种常见的设计模式进行详解。
一、创建型模式1.简单工厂模式简单工厂模式属于创建型模式,其目的是提供一个工厂类,使得创建对象的过程更加简单。
在这种模式中,使用者只需要提供所需对象的参数,而无需关心对象的具体实现细节。
简单工厂模式适合于对象创建过程较为简单的情况。
2.工厂方法模式工厂方法模式是简单工厂模式的进一步扩展,其核心在于将工厂类进行接口抽象化,使得不同的工厂类可以创建不同的对象实例。
工厂方法模式适合于对象创建过程较为复杂的情况。
它可以为工厂类添加新的产品类型,而不会影响原有的代码。
3.抽象工厂模式抽象工厂模式是工厂方法模式的进一步扩展,其目的是提供一个可以创建一系列相关或者独立的对象的接口。
在抽象工厂模式中,使用者只需要关心所需对象组合的类型,而无需关注对象的具体实现过程。
4.建造者模式建造者模式也是一种创建型模式,其目的在于将复杂对象分解为多个简单的部分,并将其组装起来形成复杂对象实例。
在建造者模式中,使用者只需要关注所需对象以及它们的组合方式,而无需关心对象的具体实现过程。
5.原型模式原型模式是一种基于克隆的创建型模式,其核心在于通过复制现有的对象实例来创建新的对象。
在原型模式中,对象实例的创建过程与对象所包含的状态密切相关。
原型模式适合于创建复杂对象实例,且这些对象实例之间是相对独立的情况。
二、结构型模式6.适配器模式适配器模式是一种结构型模式,其目的在于将一个类的接口转换为另一个类所能使用的接口。
在适配器模式中,使用者可以通过不同的适配器实现对象之间的互相调用。
7.桥接模式桥接模式是一种结构型模式,其目的在于将抽象部分与实现部分相互分离,从而使得两者可以独立变化。
业务规则校验设计模式在软件开发中,业务规则校验是非常重要的一环,它能够确保系统的正确性、一致性和安全性。
在实际开发中,业务规则校验往往是一项重复且繁琐的任务,因此设计一套有效的业务规则校验设计模式是很有必要的。
以下是一些常见的业务规则校验设计模式:1. 策略模式(Strategy Pattern)策略模式是一种行为设计模式,它定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换。
在业务规则校验中,可以将每一个校验规则看作是一个策略,通过定义一个统一的接口来抽象每一个校验规则,进而实现校验规则的可替换性。
这样在系统中新增、删除或修改校验规则时,并不需要修改其他代码,只需要替换相应的校验规则即可。
2. 责任链模式(Chain of Responsibility Pattern)责任链模式是一种行为设计模式,它将请求的发送者和接收者解耦,使得多个接收对象都有机会处理请求。
在业务规则校验中,可以将每一个校验规则看作是一个处理对象,通过定义一个统一的接口来抽象每一个校验规则,并将这些校验规则按顺序链接成一个责任链。
当一个对象接收到校验请求时,如果无法处理,则将请求传递给下一个对象,直至有一个对象处理完请求为止。
3. 观察者模式(Observer Pattern)观察者模式是一种对象行为设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。
在业务规则校验中,可以将每一个校验规则看作是一个观察者,而校验的数据则是被观察的对象。
当校验的数据发生变化时,每一个校验规则都会收到通知,并执行相应的校验逻辑。
4. 状态模式(State Pattern)状态模式是一种对象行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。
在业务规则校验中,可以将每一个校验规则看作是一个状态,通过定义一个统一的接口来抽象每一个校验规则,以及定义一个上下文对象来管理这些状态。
设计模式篇—责任链模式详解
“三从四德”之:“三从”
中国古代的妇女都要遵循“三从四德”的道德规范,那什么是三从呢?“三从”是指:未嫁从父、既嫁从夫、夫死从子。
也就是说,一位女性在结婚之前要听从于父亲,结婚之后要听从于丈夫,丈夫死了后要听从于儿子。
我们这里用程序来实现一下“三从”,首先设计类图如下:
类图非常简单,不需要过多解释,直接看代码清单。
女性接口IWomen:
古代妇女Women:
核心类Ihandler:
具体处理请求的三个类Father、Husband、Son:
场景类Client:
首先通过随机方法产生了5个古代妇女的对象,然后看她们是如何就逛街这件事去请示的。
运行结果如下所示:
代码存在的问题
“三从四德”的旧社会规范已经完整地表现出来了,但我们回头来看下这些代码,不难发现,有一下几个问题:
1.职责界定不清晰
对女儿提出的要求,应该在父亲类中做出决定,父亲有责任处理女儿的请示,因此Father 类应该是知道女儿的请求自己处理,而不是在Client类中进行组装出来,也就是说原本应该是父亲这个类做的事情抛给了其他类进行处理,不应该是这样的。
2.代码臃肿
我们在Client类中写了if...else...的判断条件,而且能随着能处理该类型的请示人员越多,判断就越多。
3.耦合过重
我们要根据Women的type来决定使用Ihandler的哪个实现类来处理请求。
如果我们要增加IHandler的实现类,那就必须要同时修改Client。
4.异常情况欠考虑
妻子只能向丈夫请示吗?如果妻子向自己的父亲请示了,父亲应该做什么处理?我们的代码没有这个处理,不符合逻辑。
那怎么解决这些问题呢?首先,分析下需求,女性提出一个请示,必然要得到一个答复,而且这个答复是唯一的,不能父亲处理完后,丈夫又处理了一遍。
然后,重新设计,我们先画出一个请示的流程图:
父亲、丈夫、儿子每个节点有两个选择:要么处理请求,做出回应,要么把请求转发到后续环节。
最后,我们按这个思路实现这个功能,修改类图如下:
从类图上看,三个子类Father、Husband、Son只要实现构造函数和父类中的抽象方法response就可以了,具体由谁处理女性提出的请求,都已经转移到了Handler抽象类中,我们看Handler怎么实现:
的级别,二是对请求做出响应。
以下是三个子类的代码:
最后,看下场景类是怎么描述这一个礼节的:
在Client中设置请求的传递顺序,先向父亲请示,不是父亲应该解决的问题,则由父亲传递到丈夫类解决,依次类推,最终的结果必然有一个返回,运行结果如下所示:
结果运行符合预期,业务调用类Client也不用去做判断到底是需要谁去处理,而且Handler 抽象类的子类可以继续增加下去,只需要扩展传递链而已,这就是我们这篇文章要谈论的主题——责任链模式。
责任链模式
责任链模式的定义是:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系,讲这些对象连城一条链,并沿着这条链传递该请求,知道有对象处理它为止。
责任链模式的通用类图如下:
首先看抽象处理者的代码:
其中的Level、Request、Response是自己项目中定义的一些类,例子如下:
抽象的处理者Handler实现三个职责:一是定义一个请求的处理方法handleMessage,唯一对外开放的方法;二是定义一个链的编排方法setNextHandler,设置下一个处理者;三是定义了具体的请求者必须实现的两个方法:定义自己能够处理的级别getHandlerLevel和具体的处理任务方法echo。
我们定义三个具体的处理者,以便可以形成一个链,代码如下:
在场景类或高层模块中对链进行组装,并传递请求,返回结果,代码如下:
在实际应用中,一般会有一个封装类对责任链模式进行封装,也就是替代Client类,直接返回链中的第一个处理者,具体链的设置不需要高层次模块关心,这样,更简化了高层次模块的调用。
责任链模式的应用
责任链模式非常显著的优点是将请求和处理分开,两者解耦,提高系统的灵活性。
责任链模式有两个非常显著的缺点:一是性能问题,每个请求都是从链头遍历到链尾,特别是链比较长的时候,性能是一个非常大的问题;二是调试很不方便。
所以,链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNextHandler方法中判断是否已经超过阈值,超过则不允许该链建立,避免无意识地破坏系统性能。