责任链设计模式
一般原则:
当请求被责任链中某个对象处理了,则停止后续调用;否则,将请求继续往下传递。
变体:
请求可以被责任链中某几个对象处理,也可以分别被每个对象处理一遍。
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);
}
}
}