职责链模式又称为责任链模式,是一种对象行为型模式。
1职责链模式结构
职责链模式结构的核心在于引入了一个抽象处理者,其结构如下图所示。
职责链模式包含以下两个角色。
(1)Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。每一个处理者的下家还是一个处理者,故在抽象处理者中定义了一个抽象处理者类型的对象(结构图中的succssor)作为其对下家的引用,通过该引用处理者可以连成一条链。
ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中的下一个对象,以便请求的转发。
2.职责链模式实现
在职责链模式中很多对象由每一个对象对其下家的引用连接起来形成一条链。请求在这个链上传递。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重写组织链和分配责任。
责任链模式的核心在于抽象处理类的设计,抽象处理者的典型代码如下:
package handlerpattern;
public abstract class Handler {
//维持对下家的引用
protected Handler successor;
public void setSuccessor(Handler handler){
this.successor=successor;
}
public abstract void handleRequest(String request);
}
在上述代码中,抽象处理者类定义了对下家的引用对象,以便将请求转发给下家,该对象的访问符可设为protected,在其子类中可以使用。在抽象处理者类中声明了抽象的请求处理方法,具体实现交由子类完成。
具体处理者是抽象处理者的子类,它有两个作用:一是处理请求,不同的具体处理者以不同的形式实现抽象请求处理方法handleRequest();二是转发请求,如果该请求超出了当前处理者类的权限,可以将该请求转发给下家。具体处理者类的典型代码如下:
package handlerpattern;
public class ConcreteHandler extends Handler{
@Override
public void handleRequest(String request) {
if(请求满足条件){
//处理请求
}
else {
this.successor.handleRequest(request);//转发请求
}
}
}
在具体处理类中通过对请求进行判断可以做出相应的处理。
需要注意的是,职责链模式并不负责创建职责链,职责链的创建工作必须由系统的其他部分来完成,一般是在使用该职责链的客户端中创建职责链。职责链模式降低了请求的发送端和接收端的耦合,使多个对象都有机会处理这个请求。典型的客户端代码片段如下:
package handlerpattern;
public class Client {
...
Handler handler1,handler2,handler3;
handler1=new ConcreteHandlerA();
handler2=new ConcreteHandlerB();
handler3=new ConcreteHandlerC();
//创建职责链
handler1.setSuccessor(handler2);
handler2.setSuccessor(handler3);
//发送请求,请求对象通常为自定义类型
handler1.handleRequest("请求对象");
...
}
3.职责链模式应用实例
类图如下图所示,抽象类Approver充当抽象处理者(抽象传递者),Director,VicePresident,President和Congress充当具体处理者(具体传递者),Purchuserequest充当请求类。
(1)PurchaseRequest:采购单类,充当请求类。
package handlerpatternexample;
public class PurchaseRequest {
private double amount;//采购金额
private int number;//采购单编号
private String purpose;//采购目的
public PurchaseRequest(double amount, int number, String purpose) {
this.amount = amount;
this.number = number;
this.purpose = purpose;
}
public double getAmount() {
return amount;
}
public int getNumber() {
return number;
}
public String getPurpose() {
return purpose;
}
public void setAmount(double amount) {
this.amount = amount;
}
public void setNumber(int number) {
this.number = number;
}
public void setPurpose(String purpose) {
this.purpose = purpose;
}
}
(2)Approver:审批者类,充当抽象处理者。
package handlerpatternexample;
public abstract class Approver {
protected Approver successor;//定义后继对象
protected String name;//审批者姓名
public Approver(String name){
this.name=name;
}
//设置后继者
public void setSuccessor(Approver successor){
this.successor=successor;
}
//抽象请求处理方法
public abstract void processRequest(PurchaseRequest request);
}
(3)Director:主任类,充当具体处理者。
package handlerpatternexample;
public class Director extends Approver{
public Director(String name) {
super(name);
}
//具体请求处理方法
@Override
public void processRequest(PurchaseRequest request) {
if(request.getAmount()<50000){
System.out.println("主任"+this.name+"审批采购单:"+request.getNumber()+
",金额:"+request.getAmount()+"元,采购目的:"+request.getPurpose()+".");//处理请求
}
else {
this.successor.processRequest(request);//转发请求
}
}
}
(4)VicePresident:副董事长类,充当具体处理者
package handlerpatternexample;
public class VicePresident extends Approver{
public VicePresident(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if(request.getAmount()<100000){
System.out.println("副董事长"+this.name+"审批采购单:"+request.getNumber()+
",金额:"+request.getAmount()+"元,采购目的:"+request.getPurpose()+".");//处理请求
}
else {
this.successor.processRequest(request);//转发请求
}
}
}
(5)President:董事长类,充当具体处理者类。
package handlerpatternexample;
public class President extends Approver{
public President(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if(request.getAmount()<500000){
System.out.println("董事长"+this.name+"审批采购单:"+request.getNumber()+
",金额:"+request.getAmount()+"元,采购目的:"+request.getPurpose()+".");//处理请求
}
else {
this.successor.processRequest(request);//转发请求
}
}
}
(6)Congress:董事会类,充当具体处理者。
package handlerpatternexample;
public class Congress extends Approver{
public Congress(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
System.out.println("召开董事会审批采购单:"+request.getNumber()+
",金额:"+request.getAmount()+"元,采购目的:"+request.getPurpose()+".");//处理请求
}
}
(7)Client:客户端测试类。
package handlerpatternexample;
public class Client {
public static void main(String[] args){
Approver wjzhang,gyang,jguo,meeting;
wjzhang=new Director("张无忌");
gyang=new VicePresident("杨过");
jguo=new President("郭靖");
meeting=new Congress("董事会");
//创建职责链
wjzhang.setSuccessor(gyang);
gyang.setSuccessor(jguo);
jguo.setSuccessor(meeting);
//创建采购单
PurchaseRequest pr1=new PurchaseRequest(45000,10001,"购买倚天剑");
wjzhang.processRequest(pr1);
PurchaseRequest pr2=new PurchaseRequest(60000,10002,"购买《葵花宝典》>");
wjzhang.processRequest(pr2);
PurchaseRequest pr3=new PurchaseRequest(160000,10003,"购买《金刚经》");
wjzhang.processRequest(pr3);
PurchaseRequest pr4=new PurchaseRequest(800000,10004,"购买桃花岛");
wjzhang.processRequest(pr4);
}
}
编译并运行程序,输出结果如下:
如果需要在系统中增加一个新的具体处理者,例如增加一个经理(Manager)角色可以审批5万元至8万元的采购单,需要编写一个新的具体处理者类Manager作为抽象处理者类Approver的子类,实现在Approver类中定义的抽象处理方法,如果采购金额大于等于8万元,则将请求转发给下家。
package handlerpatternexample;
public class Manager extends Approver{
public Manager(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if(request.getAmount()<80000){
System.out.println("经理"+this.name+"审批采购单:"+request.getNumber()+
",金额:"+request.getAmount()+"元,采购目的:"+request.getPurpose()+".");//处理请求
}
else {
this.successor.processRequest(request);//转发请求
}
}
}
由于链的创建过程有客户的负责,因此增加新的具体处理者类对原有的类库无任何影响,无须修改已有类的源代码,符合开闭原则。
在客户端代码中,如果要将新的具体请求处理者应用在系统中,需要创建新的具体处理者对象,然后将该对象加入职责链中。将客户端测试代码改为以下代码。
package handlerpatternexample;
public class Client {
public static void main(String[] args){
Approver wjzhang,gyang,jguo,meeting;
wjzhang=new Director("张无忌");
gyang=new VicePresident("杨过");
jguo=new President("郭靖");
meeting=new Congress("董事会");
Approver rhuang;
rhuang=new Manager("黄蓉");
//创建职责链
wjzhang.setSuccessor(rhuang);
rhuang.setSuccessor(gyang);
gyang.setSuccessor(jguo);
jguo.setSuccessor(meeting);
//创建采购单
PurchaseRequest pr1=new PurchaseRequest(45000,10001,"购买倚天剑");
wjzhang.processRequest(pr1);
PurchaseRequest pr2=new PurchaseRequest(60000,10002,"购买《葵花宝典》>");
wjzhang.processRequest(pr2);
PurchaseRequest pr3=new PurchaseRequest(160000,10003,"购买《金刚经》");
wjzhang.processRequest(pr3);
PurchaseRequest pr4=new PurchaseRequest(800000,10004,"购买桃花岛");
wjzhang.processRequest(pr4);
}
}
重写编译并运行程序,输出结果如下:
4.纯与不纯的职责链模式
职责链模式可以分为纯的职责链模式和不纯的职责链模式
4.1纯的职责链模式
一个纯的职责链模式要求一个具体处理者对象只能在两个行为中选择一个,要么承担全部责任,要么将责任推给下家,不允许出现某一个具体处理者对象承担了一部分或全部责任和又将责任向下传递的情况。而且在纯的职责链模式中要求一个请求必须必须被某一个处理者对象所接收,不能出现某个请求未被任何一个处理者对象处理的情况。上述例子即使纯的职责链模式。
4.2不纯的职责链模式
在一个不纯的职责链模式中允许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某请求后其后继处理者可以继续处理该请求,而且一个请求可以不被任何处理者对象所接收并处理。
参考:Java设计模式(刘伟)