责任链设计模式
一般原则:
当请求被责任链中某个对象处理了,则停止后续调用;否则,将请求继续往下传递。
变体:
请求可以被责任链中某几个对象处理,也可以分别被每个对象处理一遍。
Sample1:
日志记录为例,任务会依次传递到每一个对象上,至于是否处理则由具体对象来决定:
DEBUGE级别的,只往控制台输出;
NOTICE级别的,往控制台输出,并发送邮件;
ERROR级别的,往控制台输出,并发送邮件,并将错误记录到专门的文件中;
===》顶层接口
public interface ILogger { void log(String msg, int priority); }
===》模板方法,实现链式调用,必须持有下一个责任对象的引用
public abstract class Logger implements ILogger { public static final int ERR = 3; public static final int NOTICE = 5; public static final int DEBUGE = 7; protected int mask; //successor protected Logger nextLogger; //this can be done by use spring injection public void setNext(Logger logger) { this.nextLogger = logger; } //template method public void log(String msg, int priority) { if(priority <= mask) writeMessage(msg); //invoke next responsibility object if(nextLogger != null) { nextLogger.log(msg, priority); } } //how to log message all decided by subclass abstract protected void writeMessage(String msg); }
===》责任链中的对象1:负责向控制台输出日志
public class StdoutLogger extends Logger { public StdoutLogger(int mask) { this.mask = mask; } @Override protected void writeMessage(String msg) { System.out.println("Writing to stdout: " + msg); } }
===》责任链中的对象2:负责发送邮件
public class EmailLogger extends Logger { public EmailLogger(int mask) { this.mask = mask; } @Override protected void writeMessage(String msg) { System.out.println("Sending via e-mail: " + msg); } }
===》责任链中的对象3:负责记录错误日志
public class StderrLogger extends Logger { public StderrLogger(int mask) { this.mask = mask; } @Override protected void writeMessage(String msg) { System.err.println("Sending to stderr: " + msg); } }
===》维护责任链中处理请求的对象关系,并提供统一的外部访问
public class LogFacade { private static ILogger logger; static { initChain(); } private static void initChain() { StdoutLogger first = new StdoutLogger(Logger.DEBUGE); EmailLogger second = new EmailLogger(Logger.NOTICE); StderrLogger last = new StderrLogger(Logger.ERR); first.setNext(second); second.setNext(last); logger = first; } public void log(String msg, int priority) { logger.log(msg, priority); } }
===》测试
public class TestChain { public static void main(String[] args) { LogFacade handler = new LogFacade(); handler.log("Handled by StdoutLogger (level = 7)", Logger.DEBUGE); handler.log("Handled by StdoutLogger and EmailLogger (level = 5)", Logger.NOTICE); handler.log("Handled by all three loggers (level = 3)", Logger.ERR); } }
===》输出:
Writing to stdout: Handled by StdoutLogger (level = 7)
Writing to stdout: Handled by StdoutLogger and EmailLogger (level = 5)
Sending via e-mail: Handled by StdoutLogger and EmailLogger (level = 5)
Writing to stdout: Handled by all three loggers (level = 3)
Sending via e-mail: Handled by all three loggers (level = 3)
Sending to stderr: Handled by all three loggers (level = 3)
======================================================================
Sample2:
报销审批,不同级别的人可审批金额大小不一样
Manager -> Vice President -> President
===》封装请求
public class PurchaseRequest { public long seqNo; public double amount; public String purpose; public PurchaseRequest(long seqNo, double amonut, String purpose) { super(); this.seqNo = seqNo; this.amount = amonut; this.purpose = purpose; } }
===》接口中声明顶层方法
public interface Power { void processRequest(PurchaseRequest request); }
===》抽象类中定义模板方法
public abstract class AbstractPower implements Power { protected static final double BASE = 1000; protected double allowable = 1 * BASE; protected Power successor; public void setNext(AbstractPower successor) { this.successor = successor; } public void processRequest(PurchaseRequest request) { if(request.amount < allowable) approve(request); else if(successor != null) successor.processRequest(request); else System.out.println("Your request for $" + request.amount + " needs a board meeting!"); } protected abstract void approve(PurchaseRequest request); }
===》经理级别
public class ManagerPower extends AbstractPower { public ManagerPower(Power next){ this.allowable = 2 * BASE; this.successor = next; } @Override public void approve(PurchaseRequest request) { System.out.println("Manager's allowable is :" + this.allowable + ". Approve $" + request.amount); } }
===》副总级别
public class VicePresidentPower extends AbstractPower { public VicePresidentPower(Power successor) { this.allowable = 5 * BASE; this.successor = successor; } @Override protected void approve(PurchaseRequest request) { System.out.println("VicePresident's allowable is :" + this.allowable + ". Approve $" + request.amount); } }
===》老总级别
public class PresidentPower extends AbstractPower { public PresidentPower(Power successor) { this.allowable = 10 * BASE; this.successor = successor; } @Override protected void approve(PurchaseRequest request) { System.out.println("President's allowable is :" + this.allowable + ". Approve $" + request.amount); } }
===》构建责任链,从级别最小的开始提交审批
public class CheckAuthority { public static void main(String[] args) { //初始化责任链 Power president = new PresidentPower(null); Power vicePresident = new VicePresidentPower(president); Power manager = new ManagerPower(vicePresident); try { while(true) { System.out.println("Enter the amount to check who should approve your expenditure."); System.out.print(">"); double d = Double.parseDouble(new BufferedReader(new InputStreamReader(System.in)).readLine()); manager.processRequest(new PurchaseRequest(0, d, "General")); } } catch(Exception exc) { System.exit(1); } } }