职责链模式
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求直到有一个处理它为止。
优点:降低类之间的耦合度,使得处理类仅需要保持一个指向后继者的引用,也使得一个对象无需知道是其他哪一个对象处理其请求,对象仅需知道该请求会被正确处理。接收者和发送者都没有明确的对方信息,增强了给对象指派职责的灵活性。
缺点:因为对象不知道是其它哪一个对象处理其请求的,所以职责链模式不保证对象被接收。
使用时机:当有多个对象处理请求,而且需要动态指定处理者的时候,可以使用职责链模式。
例子:
某公司的内部财务支出需要网上审批,对于不同额度的需要不同级别的人审批。这个可以用职责链模式实现。
首先设计一个抽象类,代表审批的人
public abstract class Approver {
public abstract void approve(BorrowBill borrowBill);
public Approver getSuccessor(){ return successor; }
public void setSuccessor(Approver successor){ this.successor = successor; }
private Approver successor;
}
后面实现具体的各级别审批者,涉及金额不一样
public class DepartApprover extends Approver {
public void approve(BorrowBill borrowBill) {
if (borrowBill.getAmt() < 5000d) {
System.out.println("该员工部门主管审批了该借支单,借支单名称为:" + borrowBill.getName() + ",该借支单金额为:" + borrowBill.getAmt());
} else if (super.getSuccessor() != null) {
super.getSuccessor().approve(borrowBill);
}
}
}
public class FinanceApprover extends Approver {
public void approve(BorrowBill borrowBill) {
if (borrowBill.getAmt() >= 5000d && borrowBill.getAmt() < 10000d) {
System.out.println("财务部门主管审批了该借支单,借支单名称为:" + borrowBill.getName() + ",该借支单金额为:" + borrowBill.getAmt());
} else if (super.getSuccessor() != null) {
super.getSuccessor().approve(borrowBill);
}
}
}
public class VicepresidentApprover extends Approver {
public void approve(BorrowBill borrowBill) {
if (borrowBill.getAmt() >= 10000d && borrowBill.getAmt() < 20000d) {
System.out.println("财务副总审批了该借支单,借支单名称为:" + borrowBill.getName() + ",该借支单金额为:" + borrowBill.getAmt());
} else if (super.getSuccessor() != null) {
super.getSuccessor().approve(borrowBill);
}
}
}
public class ManagerApprover extends Approver {
public void approve(BorrowBill borrowBill) {
if (borrowBill.getAmt() >= 20000d && borrowBill.getAmt() < 50000d) {
System.out.println("公司总经理审批了该借支单,借支单名称为:" + borrowBill.getName() + ",该借支单金额为:" + borrowBill.getAmt());
} else if (super.getSuccessor() != null) {
super.getSuccessor().approve(borrowBill);
}
}
}
public class ChairmanApprover extends Approver {
public void approve(BorrowBill borrowBill) {
if (borrowBill.getAmt() >= 50000d) {
System.out.println("公司董事长审批了该借支单,借支单名称为:" + borrowBill.getName() + ",该借支单金额为:" + borrowBill.getAmt());
} else if (super.getSuccessor() != null) {
System.out.println("公司董事长没有上级了");
}
}
}
最后客户端把审批者都加进来,形成职责链
public class Client {
public static void main(String[] argv) {
Approver departApprover = new DepartApprover();
Approver financeApprover = new FinanceApprover();
Approver vicepresidentApprover = new VicepresidentApprover();
Approver managerApprover = new ManagerApprover();
Approver chairmanApprover = new ChairmanApprover();
departApprover.setSuccessor(financeApprover);
financeApprover.setSuccessor(vicepresidentApprover);
vicepresidentApprover.setSuccessor(managerApprover);
managerApprover.setSuccessor(chairmanApprover);
BorrowBill borrowBill = new BorrowBill();
borrowBill.setName("出差借支单");
borrowBill.setAmt(3000d);
departApprover.approve(borrowBill);
borrowBill.setName("出差借支单");
borrowBill.setAmt(6000d);
departApprover.approve(borrowBill);
borrowBill.setName("采购办公用品借支单");
borrowBill.setAmt(15000d);
departApprover.approve(borrowBill);
borrowBill.setName("采购原料借支单");
borrowBill.setAmt(45000d);
departApprover.approve(borrowBill);
borrowBill.setName("采购原料借支单");
borrowBill.setAmt(100000d);
departApprover.approve(borrowBill);
}
}