职责链模式包含如下角色:
Handler: 抽象处理者
ConcreteHandler: 具体处理者
Client: 客户类
职责链模式描述的请求如何沿着对象所组成的链来传递的。它将对象组成一条链,发送者将请求发给链的第一个接收者,并且沿着这条链传递,直到有一个对象来处理它或者直到最后也没有对象处理而留在链末尾端。
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,这就是职责链模式。在职责链模式中,使得每一个对象都有可能来处理请求,从而实现了请求的发送者和接收者之间的解耦。同时职责链模式简化了对象的结构,它使得每个对象都只需要引用它的后继者即可,而不必了解整条链,这样既提高了系统的灵活性也使得增加新的请求处理类也比较方便。但是在职责链中我们不能保证所有的请求都能够被处理,而且不利于观察运行时特征。
demo
入口类
package responsibility_method_mod;
import org.junit.Test;
/**
* 责任链模式
* 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
*
* 在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
*
* 介绍
* 意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
*
* 主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
*
* 何时使用:在处理消息的时候以过滤很多道。
*
* 如何解决:拦截的类都实现统一接口。
*
* 关键代码:Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。
*
* 应用实例: 1、红楼梦中的"击鼓传花"。 2、JS 中的事件冒泡。 3、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。
*
* 优点: 1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。
*
* 缺点: 1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。 3、可能不容易观察运行时的特征,有碍于除错。
*
* 使用场景: 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。
*
* 注意事项:在 JAVA WEB 中遇到很多应用。
*/
public class Client {
@Test
public void test(){
Handler handler1 = new PresidentialSuiteHandler("第一級別");//總統套房
Handler handler2 = new LuxurySuiteHandler("第二級別");//豪華套房
Handler handler3 = new CertainHotelHandler("第三級別");//旅館
Handler handler4 = new GuestHouseHandler("第四級別");//招待所
handler4.setNext(handler3);
handler3.setNext(handler2);
handler2.setNext(handler1);
//责任链模式实现接待
handler4.handelRequest("第一級別","總統拜登來訪問");
handler4.handelRequest("第二級別","國務卿布林肯來訪問");
//打印信息如下
//客人為總統級別,請在總統套房下榻
//客人為國務卿級別,請在豪華套房下榻
}
}
责任者抽象类
package responsibility_method_mod;
/**
* Handler: 抽象处理者
*/
public abstract class Handler {
Handler nextHandler;
String level;
public Handler(String level) {
this.level = level;
}
public void setNext(Handler handler) {
nextHandler= handler;
}
public abstract void handelRequest(String level, String name);
}
具体责任者,处理人 - - 旅馆
package responsibility_method_mod;
/**
* ConcreteHandler: 具体处理者
* 旅馆
*/
public class CertainHotelHandler extends Handler {
public CertainHotelHandler(String level) {
super(level);
}
@Override
public void handelRequest(String level, String name) {
if(this.level.equals(level)){
System.out.println("客人為外交部長級別,請在旅館下榻");
}else{
this.nextHandler.handelRequest(level, name);
}
}
}
具体责任者,处理人 - - 招待所
package responsibility_method_mod;
/**
* ConcreteHandler: 具体处理者
* 招待所
*/
public class GuestHouseHandler extends Handler {
public GuestHouseHandler(String level) {
super(level);
}
@Override
public void handelRequest(String level, String name) {
if(this.level.equals(level)){
System.out.println("客人為普通高管級別,請在招待所下榻");
}else{
this.nextHandler.handelRequest(level, name);
}
}
}
具体责任者,处理人 - - 豪华套房
package responsibility_method_mod;
/**
* ConcreteHandler: 具体处理者
* 豪华套房
*/
public class LuxurySuiteHandler extends Handler {
public LuxurySuiteHandler(String level) {
super(level);
}
@Override
public void handelRequest(String level, String name) {
if(this.level.equals(level)){
System.out.println("客人為國務卿級別,請在豪華套房下榻");
}else{
this.nextHandler.handelRequest(level, name);
}
}
}
具体责任者,处理人 - - 总统套房
package responsibility_method_mod;
/**
* ConcreteHandler: 具体处理者
* 总统套房
*/
public class PresidentialSuiteHandler extends Handler {
public PresidentialSuiteHandler(String level) {
super(level);
}
@Override
public void handelRequest(String level, String name) {
if(this.level.equals(level)){
System.out.println("客人為總統級別,請在總統套房下榻");
}else{
this.nextHandler.handelRequest(level, name);
}
}
}
设计模式概览