【设计模式】责任链

责任链设计模式

一般原则

当请求被责任链中某个对象处理了,则停止后续调用;否则,将请求继续往下传递。

变体

请求可以被责任链中某几个对象处理,也可以分别被每个对象处理一遍。

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);
		}
	}
}

 

 

 

 

 

猜你喜欢

转载自just2learn.iteye.com/blog/2094763