产生背景:某些时候需要设计很多对象满足用户某一请求。为了更好的组织这些对象,可以将这些对象组成一个责任链。可以让责任链上的某一个对象满足用户请求(取决于具体应用),如果这个对象能处理就反馈有关结果,如果无法处理就将用户的请求传递给责任链上的下一个对象
1. GOF引用:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
2. 理解:责任链模式是使用多个对象处理用户某一请求的成熟模式,模式的关键是将用户的请求分派给许多对象,这些对象被组织成一个责任链,即每个对象含有后继对象的引用,并要求责任链上的对象能处理用户的请求就做出相应处理后停止,如果不能处理就传递给责任链上的下一个对象。
3. 模式的两种角色:
处理者:一个接口,负责规定具体处理者处理用户请求的方法以及具体处理者设置后继对象的方法。(简而言之,规定怎么处理和怎么传递)
具体处理者:实现处理者接口的类的实例。收到用户的请求后处理者将调用接口规定的方法。能处理则处理,不能处理则传递。处理之后就结束。
注意:Java并不支持多继承,如果具体处理者需要扩展功能,那么处理者必须是接口类型。
4.类图:
5. 责任链模式举例(代码示例)
问题描述如下:用户提交一个人的身份证号码,想知道该人是否在北京、上海或天津居住。
类图:
5. 责任链模式举例(代码示例)
问题描述如下:用户提交一个人的身份证号码,想知道该人是否在北京、上海或天津居住。
类图:
具体代码如下:
package com.ChainResponsible;
public abstract interface Handler {
public abstract void handleRequest(String number);
public abstract void setNextHandler(Handler hander);
}
package com.ChainResponsible;
import java.util.ArrayList;
public class Beijing implements Handler {
private Handler handler;
private ArrayList<String> numberList; //存放身份证号码的数组线性表
public Beijing() {
super();
numberList=new ArrayList<String>();
numberList.add("11129812340930034"); //这里使用模拟的身份证号码
numberList.add("10120810340930632");
numberList.add("22029812340930034");
numberList.add("32620810340930632");
}
public void handleRequest(String number) {
if(numberList.contains(number))
System.out.println("该人在北京居住");
else{
System.out.println("该人不在北京居住");
if(handler!=null)
handler.handleRequest(number); //将请求传递给下一个处理者
}
}
public void setNextHandler(Handler handler) {
this.handler=handler;
}
}
package com.ChainResponsible;
import java.util.ArrayList;
public class Shanghai implements Handler {
private Handler handler;
private ArrayList<String> numberList;
public Shanghai() {
super();
numberList=new ArrayList<String>();
numberList.add("34529812340930034"); //这里使用模拟的身份证号码
numberList.add("98720810340430632");
numberList.add("36529812340930034");
numberList.add("77720810340930632");
}
public void handleRequest(String number) {
if(numberList.contains(number))
System.out.println("该人在上海居住");
else{
System.out.println("该人不在上海居住");
if(handler!=null)
handler.handleRequest(number);
}
}
public void setNextHandler(Handler handler) {
this.handler=handler;
}
}
package com.ChainResponsible;
import java.util.ArrayList;
public class Tianjin implements Handler {
private Handler handler;
private ArrayList<String> numberList;
public Tianjin() {
super();
numberList = new ArrayList<String>();
numberList.add("10029812340930034"); // 这里使用模拟的身份证号码
numberList.add("20020810340430632");
numberList.add("30029812340930034");
numberList.add("50020810340930632");
}
public void handleRequest(String number) {
if (numberList.contains(number))
System.out.println("该人在天津居住");
else {
System.out.println("该人不在天津居住");
if (handler != null)
handler.handleRequest(number);
}
}
public void setNextHandler(Handler handler) {
this.handler = handler;
}
}
package com.ChainResponsible;
public class Application {
private Handler beijing,shanghai,tianjin;
public void createChain(){
beijing=new Beijing();
shanghai=new Shanghai();
tianjin=new Tianjin();
beijing.setNextHandler(shanghai);
shanghai.setNextHandler(tianjin);
}
public void responseClient(String number){
beijing.handleRequest(number);
}
public static void main(String[] args) {
Application application=new Application();
application.createChain();
application.responseClient("10029812340930034");
}
}
6.责任链模式的优点:
① 对象只和自己的后继是低耦合关系
② 当在处理者中分配职责时,责任链给应用程序更多灵活性(最有可能处理用户请求的对象放于责任链前面)
③ 可以动态增加、删除处理者或重新指派处理者的职责和处理者之间的先后顺序
④ 责任链的用户不必知道处理者的信息,用户不会知道哪个对象处理了它的请求。
7.适合使用责任链模式的情景:
① 多个对象处理用户请求,希望程序在运行时期自动确定处理用户的那个对象
② 程序希望动态制定可处理用户请求的对象集合