责任链模式(Iterator Pattern),是行为型设计模式之一,责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
责任链模式的定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它位置。
责任链模式的使用场景
多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
在请求处理者不明确的情况下向多个对象中的一个提交一个请求
需要动态指定一组对象处理请求
UML类图
角色介绍:
Handler:抽象处理者角色,声明一个请求处理的方式,并在其中保持一个对下一个处理节点Handler对象的引用。
ConcreteHandler:具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个节点上的处理对象。
简单实现
//抽闲处理者
public abstract class Handler {
protected Handler successor; // 下一节点的处理者
/**
* 请求处理
* @param condition 请求条件
*/
public abstract void handleRequest(String condition);
}
//具体的处理者1
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String condition) {
if(condition.equals("ConcreteHandler1")) {
System.out.println("ConcreteHandler1 handled");
return;
} else {
successor.handleRequest(condition);
}
}
}
//具体的处理者1
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String condition) {
if(condition.equals("ConcreteHandler2")) {
System.out.println("ConcreteHandler2 handled");
return;
} else {
successor.handleRequest(condition);
}
}
}
public class Client {
public static void main(String[] args){
//构造一个ConcreteHandler1对象
ConcreteHandler1 handler1 = new ConcreteHandler1();
//构造一个ConcreteHandler2对象
ConcreteHandler2 handler2 = new ConcreteHandler2();
//设置handler1的下一个节点
handler1.successor = handler2;
//设置handler2的下一个节点
handler2.successor = handler1;
//处理请求
handler1.handleRequest("ConcreteHandler2");
}
}
这是简化版通用的模式代码,因为其形式是固定的,就是一个字符串,来判断是否与之匹配,然而大多数情况下,责任链中的请求和对应的处理规则是不尽相同的,这种情况下可以将请求进行封装,同时对请求的处理规则也进行封装作为一个独立的对象,类图如下:
实现如下:
//抽象处理者
public abstract class AbstractHandler {
protected AbstractHandler nextHandler; // 下一节点上的处理者的对象
public final void handleRequest(AbstractRequest request){
if(getHandlerLevel() == request.getRequestLevel()) {
// 一致则由该处理对象处理
handle(request);
}else {
//否则将该请求对象转发给下一个节点上的请求对象
if(nextHandler != null) {
nextHandler.handleRequest(request);
}else{
//当所有处理者都不能处理该请求时输出
System.out.println("All of handler can not handle the request");
}
}
}
/**
* 获取处理者对象的处理级别
* @return 处理级别
*/
protected abstract int getHandlerLevel();
/**
* 每个处理者对象的具体处理方式
* @param request 请求者对象
*/
protected abstract void handle(AbstractRequest request);
}
//请求者1
public class Request1 extends AbstractRequest {
public Request1(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 1;
}
}
//请求者2
public class Request2 extends AbstractRequest {
public Request2(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 2;
}
}
// 抽象请求者
public abstract class AbstractRequest {
private Object obj; //处理对象
public AbstractRequest(Object obj){
this.obj = obj;
}
/**
* 获取处理的内容对象
* @return 具体的内容对象
*/
public Object getContent(){
return obj;
}
/**
* 获取请求级别
* @return 请求级别
*/
public abstract int getRequestLevel();
}
接下来是三个处理者和三个请求者
//处理者1
public class Handler1 extends AbstractHandler {
@Override
protected int getHandlerLevel() {
return 1;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler1 handle request:"+request.getRequestLevel());
}
}
//处理者2
public class Handler2 extends AbstractHandler {
@Override
protected int getHandlerLevel() {
return 2;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler1 handle request:"+request.getRequestLevel());
}
}
//处理者3
public class Handler3 extends AbstractHandler {
@Override
protected int getHandlerLevel() {
return 3;
}
@Override
protected void handle(AbstractRequest request) {
System.out.println("Handler1 handle request:"+request.getRequestLevel());
}
}
//请求者1
public class Request1 extends AbstractRequest {
public Request1(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 1;
}
}
//请求者2
public class Request2 extends AbstractRequest {
public Request2(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 2;
}
}
//请求者3
public class Request3 extends AbstractRequest {
public Request3(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 3;
}
}
下面是Client客户端类
public class Client {
public static void main(String[] args){
//构造3个处理者对象
AbstractHandler handler1 = new Handler1();
AbstractHandler handler2 = new Handler2();
AbstractHandler handler3 = new Handler3();
//设置当前处理者对象下一个节点的处理者对象
handler1.nextHandler = handler2;
handler2.nextHandler = handler3;
//构造3个请求者对象
AbstractRequest request1 = new Request1("Request1");
AbstractRequest request2 = new Request1("Request2");
AbstractRequest request3 = new Request1("Request3");
//总是从链式的首端发起请求
handler1.handleRequest(request1);
handler1.handleRequest(request2);
handler1.handleRequest(request3);
}
}
纯的责任链和不纯的责任链
对于责任链中的一个处理者对象,其只有两个行为,一是处理请求,二是将请求转送给下一个节点,不允许某个处理者对象在处理了请求后又将请求转送给上一个节点的情况。对于一条责任链来说,这个请求最终只有两种情况,一是被某个处理对象所处理,另一个是所有对象均未对其处理,对于前一种情况我们称该责任链为纯的责任链,对于后一种情况我们称为不纯的责任链,在实际应用中,我们所见到的责任链模式大多为不纯的责任链。
优缺点
职责链模式的优点:
1 ) 降低耦合度 :该模式使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需知道该请求会被“正确”地处理。接收者和发送者都没有对方的明确的信息,且链中的对象不需知道链的结构。
2) 职责链可简化对象的相互连接 : 结果是,职责链可简化对象的相互连接。它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。
3) 增强了给对象指派职责( R e s p o n s i b i l i t y )的灵活性 :当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。你可以将这种机制与静态的特例化处理对象的继承机制结合起来使用。
4)增加新的请求处理类很方便
职责链模式的缺点:
1) 不能保证请求一定被接收。既然一个请求没有明确的接收者,那么就不能保证它一定会被处理 —该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。
2) 系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。
总结
在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
职责链模式的主要优点在于可以降低系统的耦合度,简化对象的相互连接,同时增强给对象指派职责的灵活性,增加新的请求处理类也很方便;其主要缺点在于不能保证请求一定被接收,且对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。