1、责任链模式的定义
定义: 使多个对象都有机会处理请求,从而避免请求的发送者与请求处理者耦合在一起。将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
类型: 对象行为型模式
实质: 责任链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,从而实现请求发送者与请求处理者的解耦。
2.类图
- Handler(抽象处理者):处理请求的接口,一般设计为具有抽象请求处理方法的抽象类,以便于不同的具体处理者进行继承,从而实现具体的请求处理方法。此外,由于每一个请求处理者的下家还是一个处理者,因此抽象处理者本身还包含了一个本身的引用( successor)作为其对下家的引用,以便将处理者链成一条链;
- ConcreteHandler(具体处理者):抽象处理者的子类,可以处理用户请求,其实现了抽象处理者中定义的请求处理方法。在具体处理请求时需要进行判断,若其具有相应的处理权限,那么就处理它;否则,其将请求 转发 给后继者,以便让后面的处理者进行处理。
在责任链模式里,由每一个请求处理者对象对其下家的引用而连接起来形成一条请求处理链。请求将在这条链上一直传递,直到链上的某一个请求处理者能够处理此请求。事实上,发出这个请求的客户端并不知道链上的哪一个请求处理者将处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
3.主要的思路
1、对请求处理者的抽象
责任链模式的核心在于对 请求处理者的抽象。在实现过程中,抽象处理者一般会被设定为 抽象类,其典型实现代码如下所示:
public abstract class Handler {
// protected :维持对下家的引用
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor=successor;
}
public abstract void handleRequest(String request);
}
上述代码中,抽象处理者类定义了对下家的引用 (其一般用 protected 进行修饰),以便将请求转发给下家,从而形成一条请求处理链。同时,在抽象处理者类中还声明了抽象的请求处理方法,以便由子类进行具体实现。
2、对请求处理者的抽象
具体处理者是抽象处理者的子类,具体处理者类的典型代码如下:
public class ConcreteHandler extends Handler {
public void handleRequest(String request) {
if (请求满足条件) {
//处理请求
}else {
this.successor.handleRequest(request); //转发请求
}
}
}
在具体处理类中,通过对请求进行判断以便做出相应的处理,因此,其一般具有两大作用:
处理请求,不同的具体处理者以不同的形式实现抽象请求处理方法 handleRequest();
转发请求,若该请求超出了当前处理者类的权限,可以将该请求转发给下家;
需要注意的是,责任链模式并不创建职责链,职责链的创建工作必须由系统的其他部分来完成,一般由使用该责任链的客户端创建。职责链模式降低了请求的发送者和请求处理者之间的耦合,从而使得多个请求处理者都有机会处理这个请求。
4.实验题:
在军队中,一般根据战争规模的大小和重要性由不同级别的长官(Officer)来下达作战命令,情报人员向上级递交军情(如敌人的数量),作战命令需要上级批准,如果直接上级不具备下达命令的权力,则上级又传给上级,直到有人可以决定为止。现使用职责链模式来模拟该过程,客户类(Client)模拟情报人员,首先向级别最低的班长(Banzhang)递交任务书(Mission),即军情,如果超出班长的权力范围,则传递给排长(Paizhang),排长如果也不能处理则传递给营长(Yingzhang),如果营长也不能处理则需要开会讨论。我们设置这几级长官的权力范围分别是:
(1) 敌人数量<10,班长下达作战命令;
(2) 10<=敌人数量<50,排长下达作战命令;
(3) 50<=敌人数量<200,营长下达作战命令;
(4) 敌人数量>=200,需要开会讨论再下达作战命令。
代码实现:
(1)请求任务类:
class Mission{
private int enemyNumber;
public Mission(int enemyNumber){
this.enemyNumber=enemyNumber;
}
public void setEnemyNumber(int enemyNumber){
this.enemyNumber=enemyNumber;
}
public int getEnemyNumber(){
return this.enemyNumber;
}
}
(2)抽象处理者类
//抽象处理者(军官)
abstract class Officer{
// 定义后继处理对象
protected Officer officer;
// 设置后继者
public void setOfficer(Officer officer){
this.officer=officer;
}
//抽象请求处理方法
public abstract void processRequest(Mission mission);
}
(3)具体处理类
//具体处理者(班长)
class Banzhang extends Officer{
public void processRequest(Mission mission){
if(mission.getEnemyNumber()<10){
System.out.println("班长下达作战命令");
}else {
this.officer.processRequest(mission);
}
}
}
//具体处理者(排长)
class Paizhang extends Officer{
public void processRequest(Mission mission){
if(mission.getEnemyNumber()>=10&&mission.getEnemyNumber()<50){
System.out.println("排长下达作战命令");
}else {
this.officer.processRequest(mission);
}
}
}
//具体处理者(营长)
class Yingzhang extends Officer{
public void processRequest(Mission mission){
if(mission.getEnemyNumber()>=50&&mission.getEnemyNumber()<200){
System.out.println("营长下达作战命令");
}else {
this.officer.processRequest(mission);
}
}
}
//具体处理者(会议处理)
class Metting extends Officer{
public void processRequest(Mission mission){
if(mission.getEnemyNumber()>=200){
System.out.println("开会讨论下达作战命令");
}
}
}
(4)客户端
public class responsibilityChain {
public static void main(String[] args) {
Officer banzhang,paizhang,yingzhang,metting;
banzhang=new Banzhang();
paizhang=new Paizhang();
yingzhang=new Yingzhang();
metting=new Metting();
// 创建责任链
banzhang.setOfficer(paizhang);
paizhang.setOfficer(yingzhang);
yingzhang.setOfficer(metting);
// 创建军队任务,从班长开始处理
System.out.println("敌人数量为10时");
Mission mission1 =new Mission(10);
banzhang.processRequest(mission1);
System.out.println("敌人数量为20时");
Mission mission2 =new Mission(20);
banzhang.processRequest(mission2);
System.out.println("敌人数量为100时");
Mission mission3 =new Mission(100);
banzhang.processRequest(mission3);
System.out.println("敌人数量为300时");
Mission mission4 =new Mission(300);
banzhang.processRequest(mission4);
}
}
参考文章: