责任链模式:将能够处理同一类请求的对象连成一条链,使这些对象都有机会处理请求,所提交的请求沿着链传递。从而避免请求的发送者和接受者之间的耦合关系。链上的对象逐个判断是否有能力处理该请求,如果能则就处理,如果不能,则传给链上的下一个对象。直到有一个对象处理它为止。
特点
1)被观察者需要持有一个或者多个观察者对象。
2)系统中一个模块的变化,某些模块也会跟随着变化。
UML
在责任链模式中,作为请求接收者的多个对象通过对其后继的引用而连接起来形成一条链。请求在这个链上传递,直到链上某一个接收者处理这个请求。每个接收者都可以选择自行处理请求或是向后继传递请求。
责任链模式的结构
下面使用了一个责任链模式的最简单的实现。
责任链模式涉及到的角色如下所示:
● 抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
● 具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
请假逻辑
/* * 处理人,负责处理请假申请 */ public abstract class LeaveHandler { /* * 直接后继,用于传递请求 */ protected LeaveHandler successor; public void setSuccessor(LeaveHandler successor) { this.successor = successor; } /* * 处理请假申请 */ public abstract void disposeLeave(int day); }
/* * 项目经理可以批准一天的假期 */ public class Lead extends LeaveHandler { @Override public void disposeLeave(int day) { if (day <= 1) { System.out.println("我叫做胡经理,我可以处理" + day + "的假期"); } else { // 如果他处理不了就向上传递请求 successor.disposeLeave(day); } } }
/* * 技术总监可以批准三天的假期 */ public class CTO extends LeaveHandler{ @Override public void disposeLeave(int day) { if (day <= 3) { System.out.println("我叫做王总监,我可以处理" + day + "内的假期"); } else { // 如果他处理不了就向上传递请求 successor.disposeLeave(day); } } }
/* * 人事部门老大可以批准一个星期内的假期 */ public class HrBoos extends LeaveHandler{ @Override public void disposeLeave(int day) { if (day <= 5) { System.out.println("我叫做张老大,我可以处理" + day + "内的假期"); } else { // 如果他处理不了就向上传递请求 successor.disposeLeave(day); } } }
/* * 老板,只要他同意,你可以无限期休假 */ public class CEO extends LeaveHandler { @Override public void disposeLeave(int day) { //因为这里所有的假期他都可以处理所以没有判断 System.out.println("我叫做CEO,我可以处理" + day + "的假期"); } }
public class LeaveHandlerFactory { /*/ * 创建工厂方法 */ public static LeaveHandler createHandler() { LeaveHandler lead = new Lead(); LeaveHandler cto = new CTO(); LeaveHandler hrBoos = new HrBoos(); LeaveHandler ceo = new CEO(); lead.setSuccessor(cto); cto.setSuccessor(hrBoos); hrBoos.setSuccessor(ceo); return lead; } }
public class test { private LeaveHandler handler; public void setHandler(LeaveHandler handler) { this.handler = handler; } public void requestDiscount(int day){ handler.disposeLeave(day); } public static void main(String[] args) { test test=new test(); test.setHandler(LeaveHandlerFactory.createHandler()); test.requestDiscount(8); } }我叫做CEO,我可以处理8的假期