设计模式——职责链模式

mac2025-08-23  2

1 简介

职责链模式(Chain of Responsibility Pattern)定义:避免请求发送者与接受者耦合在一起,让多个对象都有可能接受请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

2 代码

(1)抽象处理者(Handler)

public abstract class Handler { protected Handler successor; //后继者 public void setSuccessor(Handler successor) { this.successor=successor; } public abstract void handleRequest(String request); }

(2)具体处理者(ConcreteHandler)

public class ConcreteHandlerA extends Handler { @Override public void handleRequest(String request) { if( request满足条件 ) { ... //处理请求 }else { successor.handleRequest(request); //将职责抛给下家 } } }

3 应用案例

假条审批系统:如果学生请假天数小于或等于3天,辅导员可以审批该假条;如果大于3天,小于或等于7天,系主任可以审批;如果大于7天,小于或等于30天,院长可以审批;超过30天,提示相应拒绝信息。

(1)请求类(LeaveRequest)

public class LeaveRequest { public String leaveName; public int leaveDays; public LeaveRequest(String leaveName,int leaveDays) { this.leaveName=leaveName; this.leaveDays=leaveDays; } }

(2)抽象处理者(Leader)

public abstract class Leader { String name; protected Leader successor; //后继者 public Leader(String name) { this.name=name; } public void setSuccessor(Leader successor) { this.successor=successor; } public abstract void handleRequest(LeaveRequest request); }

(3)具体处理者(Counselor、Director、Dean)

public class Counselor extends Leader { public Counselor(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.leaveDays<=3) { System.out.println("辅导员"+name+"审批学生"+request.leaveName+"的请假条,请假天数为"+request.leaveDays+"天"); }else { successor.handleRequest(request); //将职责抛给下家 } } } public class Director extends Leader { public Director(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.leaveDays<=7) { System.out.println("系主任"+name+"审批学生"+request.leaveName+"的请假条,请假天数为"+request.leaveDays+"天"); }else { successor.handleRequest(request); //将职责抛给下家 } } } public class Dean extends Leader { public Dean(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if(request.leaveDays<=30) { System.out.println("院长"+name+"审批学生"+request.leaveName+"的请假条,请假天数为"+request.leaveDays+"天"); }else { System.out.println("莫非你想休学,居然请假"+request.leaveDays+"天"); } } }

(4)客户端(Client)

public class Client { public static void main(String[] args) { Leader counselor=new Counselor("张三"); Leader director=new Director("李四"); Leader dean=new Dean("王五"); counselor.setSuccessor(director); director.setSuccessor(dean); counselor.handleRequest(new LeaveRequest("stuA",2)); counselor.handleRequest(new LeaveRequest("stuB",6)); counselor.handleRequest(new LeaveRequest("stuC",15)); counselor.handleRequest(new LeaveRequest("stuD",40)); } } 辅导员张三审批学生stuA的请假条,请假天数为2天 系主任李四审批学生stuB的请假条,请假天数为6天 院长王五审批学生stuC的请假条,请假天数为15天 莫非你想休学,居然请假40天

4 JDK中应用

在早期的 Java AWT 事件模型(JDK 1.0及更早),广泛使用了职责链模式,这种事件处理机制又叫事件浮升(Event Bubbling)机制。

由于窗口组件(如按钮、文本框等)一般都位于容器组件中,因此当事件发生在某一个组件上时,通过组件对象的 handleEvent() 方法将事件传递给相应的事件处理方法,该事件处理方法将处理此事件,然后决定是否将该事件向上一级容器组件传播,如果没有相应的事件处理方法,则会将事件传递给包含组件的上一级容器,以此类推;上一级容器组件在接到事件之后可以继续处理此事件,并决定是否继续向上级容器组件传播,如此反复,直到事件到达顶层容器组件为止;如果一直传到最顶层容器仍没有处理方法,则该事件不予处理。

由于这种基于职责链模式的事件处理方式存在代码维护困难、重用性差、存在大量条件语句、处理速度慢等缺点,从JDK 1.1 以后,使用观察者模式代替职责链模式来处理事件。目前,在 JavaScript 中仍然可以使用这种事件浮升机制来进行事件处理。

最新回复(0)