return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限:
// 抽象处理者:审批者
abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者public void setSuccessor(Approver successor) {this.successor = successor;}// 处理请求的抽象方法public abstract void processRequest(PurchaseRequest request);
}// 具体处理者:主任
class Director extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 10000) {System.out.println("主任审批了金额为 " + request.getAmount() + " 的采购申请");} else if (successor != null) {successor.processRequest(request);}}
}// 具体处理者:经理
class Manager extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 50000) {System.out.println("经理审批了金额为 " + request.getAmount() + " 的采购申请");} else if (successor != null) {successor.processRequest(request);}}
}// 具体处理者:副总裁
class VicePresident extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 100000) {System.out.println("副总裁审批了金额为 " + request.getAmount() + " 的采购申请");} else if (successor != null) {successor.processRequest(request);}}
}// 具体处理者:总裁
class President extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 500000) {System.out.println("总裁审批了金额为 " + request.getAmount() + " 的采购申请");} else {System.out.println("金额过大,需要董事会讨论");}}
}// 请求类
class PurchaseRequest {private double amount; // 金额private String purpose; // 用途public PurchaseRequest(double amount, String purpose) {this.amount = amount;this.purpose = purpose;}public double getAmount() {return amount;}public String getPurpose() {return purpose;}
}// 客户端类
public class Client {public static void main(String[] args) {// 创建处理者Approver director = new Director();Approver manager = new Manager();Approver vicePresident = new VicePresident();Approver president = new President();// 设置责任链director.setSuccessor(manager);manager.setSuccessor(vicePresident);vicePresident.setSuccessor(president);// 创建采购申请PurchaseRequest request1 = new PurchaseRequest(5000, "购买办公用品");PurchaseRequest request2 = new PurchaseRequest(30000, "购买电脑设备");PurchaseRequest request3 = new PurchaseRequest(80000, "购买服务器");PurchaseRequest request4 = new PurchaseRequest(300000, "购买办公大楼");// 处理请求director.processRequest(request1);director.processRequest(request2);director.processRequest(request3);director.processRequest(request4);}
}
一、能不能连写?
// 抽象处理者:审批者
abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者并返回当前实例public Approver setSuccessor(Approver successor) {this.successor = successor;return this;}// 处理请求的抽象方法public abstract void processRequest(PurchaseRequest request);
}// 具体处理者:主任
class Director extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 10000) {System.out.println("主任审批了金额为 " + request.getAmount() + " 的采购申请");} else if (successor != null) {successor.processRequest(request);}}
}// 具体处理者:经理
class Manager extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 50000) {System.out.println("经理审批了金额为 " + request.getAmount() + " 的采购申请");} else if (successor != null) {successor.processRequest(request);}}
}// 具体处理者:副总裁
class VicePresident extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 100000) {System.out.println("副总裁审批了金额为 " + request.getAmount() + " 的采购申请");} else if (successor != null) {successor.processRequest(request);}}
}// 具体处理者:总裁
class President extends Approver {@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 500000) {System.out.println("总裁审批了金额为 " + request.getAmount() + " 的采购申请");} else {System.out.println("金额过大,需要董事会讨论");}}
}// 请求类
class PurchaseRequest {private double amount; // 金额private String purpose; // 用途public PurchaseRequest(double amount, String purpose) {this.amount = amount;this.purpose = purpose;}public double getAmount() {return amount;}public String getPurpose() {return purpose;}
}// 客户端类
public class Client {public static void main(String[] args) {// 创建处理者Approver director = new Director();Approver manager = new Manager();Approver vicePresident = new VicePresident();Approver president = new President();// 链式设置责任链director.setSuccessor(manager).setSuccessor(vicePresident).setSuccessor(president);// 创建采购申请PurchaseRequest request1 = new PurchaseRequest(5000, "购买办公用品");PurchaseRequest request2 = new PurchaseRequest(30000, "购买电脑设备");PurchaseRequest request3 = new PurchaseRequest(80000, "购买服务器");PurchaseRequest request4 = new PurchaseRequest(300000, "购买办公大楼");// 处理请求director.processRequest(request1);director.processRequest(request2);director.processRequest(request3);director.processRequest(request4);}
}
主要改动点:
- 在
Approver
抽象类里,把setSuccessor
方法的返回值类型改成了Approver
,并让它返回this
。 - 客户端代码中的责任链设置从原来的逐行调用转变为链式调用,极大地提升了代码的可读性。
注意事项:
- 链式调用的本质是,后一个处理者会覆盖前一个处理者设置的
successor
。在这个例子中,真正生效的责任链是vicePresident -> president
。 - 要构建正确的责任链,应该按照
director -> manager -> vicePresident -> president
这样的顺序来设置。你可以通过以下方式实现:
director.setSuccessor(manager);
manager.setSuccessor(vicePresident);
vicePresident.setSuccessor(president);
二、return this;返回的是谁?
在责任链模式的代码里,return this;
返回的是当前正在执行setSuccessor
方法的处理者实例。下面结合具体例子详细说明:
1. setSuccessor
方法的返回值
在Approver
抽象类中,setSuccessor
方法经过修改后返回this
:
public Approver setSuccessor(Approver successor) {this.successor = successor;return this; // 返回当前处理者实例
}
this
的含义:在某个具体处理者(像Director
、Manager
等)调用setSuccessor
方法时,this
指的就是该处理者对象。
2. 链式调用的执行流程
来看客户端代码里的链式调用:
director.setSuccessor(manager).setSuccessor(vicePresident).setSuccessor(president);
执行步骤如下:
⑴.director.setSuccessor(manager)
- 把
manager
设为director
的下一个处理者。 - 返回
director
对象(也就是this
)。
⑵.setSuccessor(vicePresident)
- 由于第一步返回的是
director
,所以这里实际上是director.setSuccessor(vicePresident)
。 - 这就会覆盖掉
director
原来的successor
(原本是manager
),将其更新为vicePresident
。 - 再次返回
director
对象。
⑶.setSuccessor(president)
- 同理,这里是
director.setSuccessor(president)
。 - 又一次覆盖
director
的successor
,现在变成了president
。 - 还是返回
director
对象。
3. 最终形成的责任链
经过上述链式调用后,责任链的结构是:
director → president
- 问题所在:
manager
和vicePresident
被排除在了责任链之外,这显然不是我们期望的结果。
4. 正确构建责任链的方法
要构建director → manager → vicePresident → president
这样正确的责任链,应该依次设置每个处理者的下一个处理者:
director.setSuccessor(manager); // director 的下一个是 manager
manager.setSuccessor(vicePresident); // manager 的下一个是 vicePresident
vicePresident.setSuccessor(president); // vicePresident 的下一个是 president
5.总结
return this
的作用:它使得方法可以被链式调用,但在构建责任链时,必须谨慎使用,保证每个处理者的successor
设置正确。- 常见错误:直接链式调用
setSuccessor
会导致前面设置的successor
被覆盖,就像例子中最后只有director → president
这一条链路。
三、successor被覆盖是什么意思?
在责任链模式中,"successor 被覆盖" 指的是在设置处理者链时,由于错误地使用链式调用,导致先前设置的下一个处理者(successor)被后续操作意外替换的情况。以下通过具体示例详细解释:
1. 正确的责任链设置
责任链模式要求每个处理者的successor
指向下一个正确的处理者。例如:
director.setSuccessor(manager); // director → manager
manager.setSuccessor(vicePresident); // manager → vicePresident
vicePresident.setSuccessor(president); // vicePresident → president
此时的责任链结构为:
director → manager → vicePresident → president
2. 错误的链式调用导致覆盖问题
如果误用链式调用,例如:
director.setSuccessor(manager).setSuccessor(vicePresident).setSuccessor(president);
执行过程分解:
-
director.setSuccessor(manager)
director
的successor
被设为manager
。- 方法返回
director
(即this
)。
-
.setSuccessor(vicePresident)
- 由于返回的是
director
,实际执行的是director.setSuccessor(vicePresident)
。 - 覆盖了第一步设置的
successor
,现在director
的successor
变成vicePresident
,manager
被排除。
- 由于返回的是
-
.setSuccessor(president)
- 同理,执行
director.setSuccessor(president)
。 - 再次覆盖,
director
的successor
最终变为president
,vicePresident
也被排除。
- 同理,执行
最终责任链结构:
director → president
中间的manager
和vicePresident
被完全跳过,这就是 **"successor 被覆盖"** 的结果。
3. 为什么会被覆盖?
-
return this
的副作用:
在链式调用中,每次调用setSuccessor
都返回当前处理者(如director
),导致后续的setSuccessor
总是作用于同一个处理者(如director
),从而覆盖之前的设置。 -
正确链式调用的写法:
如果要使用链式语法,必须确保每次调用返回不同的处理者:
director.setSuccessor(manager); // 返回 director(忽略)
manager.setSuccessor(vicePresident); // 返回 manager(忽略)
vicePresident.setSuccessor(president); // 返回 vicePresident(忽略)
这种写法虽然语法上是链式的,但实际是分步骤设置不同处理者的 successor,避免覆盖。