责任链模式(Chain of Responsibility)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止。责任链模式把多个处理器串成链,然后让请求在链上传递:
模拟场景:一批账单,数额低于1000的由manager处理,数额高于1000但是小于10000的由boss解决,数额高于10000的由leader解决.
模拟请求类
class Request{
private String name;
private BigDecimal amount;
public Request(String name,BigDecimal amount){
this.name=name;
this.amount=amount;
}
public String getName(){
return name;
}
public BigDecimal getAmount(){
return amount;
}
}
抽象出处理器
interface Handler{
Boolean process(Request request);
}
manager处理器
class ManagerHandler implements Handler{
public Boolean process(Request request) {
if(request.getAmount().compareTo(BigDecimal.valueOf(1000))>0){
return null;
}
return !request.getName().equalsIgnoreCase("bob");//也拦截bob的请求 跟bob过不去
}
}
Boss处理器
class BossHandler implements Handler{
public Boolean process(Request request) {
if(request.getAmount().compareTo(BigDecimal.valueOf(10000))>0){
return null;
}
return !request.getName().equalsIgnoreCase("alice");//也拦截bob的请求
}
}
leader处理器
class LeaderHandler implements Handler{
public Boolean process(Request request) {
return !request.getName().equalsIgnoreCase("mack");//也拦截bob的请求
}
}
构建责任链
class HandlerChain{
private List<Handler> handlers = new ArrayList<Handler>();
public void addHandler(Handler handler){
handlers.add(handler);
}
public boolean process(Request request){
for(Handler handler:handlers){
Boolean r = handler.process(request);
if(r!=null){
System.out.println(request+" "+(r?"Approved by ": " denied by ") + handler.getClass().getSimpleName());
return r;
}
}
throw new RuntimeException("could not handler request "+ request);
}
}
main方法测试
public class ResponsibilityChain {
private static HandlerChain chain = new HandlerChain();
static {
chain.addHandler(new ManagerHandler());
chain.addHandler(new BossHandler());
chain.addHandler(new LeaderHandler());
}
public static void main(String[] args) {
chain.process(new Request("Bob", new BigDecimal("123.45")));
chain.process(new Request("Alice", new BigDecimal("1234.56")));
chain.process(new Request("Bill", new BigDecimal("12345.67")));
chain.process(new Request("John", new BigDecimal("123456.78")));
}
}