是將鏈中每個節點看做是一個對象, 每一個節點處理的請求均不一樣, 且內部自動維護一個下一節點對象。 當一個請求從鏈式的首端發出時, 會沿着鏈的路徑依次傳遞給每個節點對象, 直至有對象處理這個請求爲止。 屬於行爲型模式
適用場景:
一、多個對象能夠處理同一個請求, 但具體由那個對象處理則在運行時動態決定;
二、在不明確指定接收者的狀況下, 向多個對象中的一個提交一個請求
三、可動態指定一組對象處理請求java
public abstract class Handler { protected Handler nextHandler; public void setNextHanlder(Handler successor) { this.nextHandler = successor; } public abstract void handleRequest(String request); }
public class ConcreteHandlerA extends Handler{ private static final String REQUEST_A = "requestA"; @Override public void handlerRequest(String request) { if (REQUEST_A.equals(request)) { System.out.println(this.getClass().getSimpleName() + "deal with request: " + request); return; } if (!ObjectUtils.isEmpty(this.nextHandler)) { this.nextHandler.handlerRequest(request); } } }
public class ConcreteHandlerB extends Handler{ private static final String REQUEST_B = "requestB"; @Override public void handlerRequest(String request) { if (REQUEST_B.equals(request)) { System.out.println(this.getClass().getSimpleName() + "deal with request: " + request); return; } if (!ObjectUtils.isEmpty(this.nextHandler)) { this.nextHandler.handlerRequest(request); } } }
public class Test { public static void main(String[] args) { Handler handlerA = new ConcreteHandlerA(); Handler handlerB = new ConcreteHandlerB(); handlerA.setNextHandler(handlerB); System.out.println("=============="); handlerA.handlerRequest("requestB"); } }
======================================================================================框架
public abstract class Handler { protected Handler next; public void setNext(Handler next) { this.next = next; } /** * 處理器 * @param member */ public abstract void doHandler(Member member); }
public class ValidateHandler extends Handler{ @Override public void doHandler(Member member) { if(StringUtils.isEmpty(member.getLoginName()) || StringUtils.isEmpty(member.getLoginPass())){ System.out.println("用戶名和密碼爲空"); return; } System.out.println("用戶名和密碼不爲空,能夠往下執行"); next.doHandler(member); } }
public class LoginHandler extends Handler{ @Override public void doHandler(Member member) { System.out.println("登陸成功!"); member.setRoleName("管理員"); next.doHandler(member); } }
public class AuthHandler extends Handler { @Override public void doHandler(Member member) { if (!"管理員".equals(member.getRoleName())) { System.out.println("您不是管理員,沒有操做權限"); return; } System.out.println("容許操做"); } }
public class MemberService { public void login(String loginName, String loginPass) { Handler validateHandler = new ValidateHandler(); Handler loginHandler = new LoginHandler(); Handler authHandler = new AuthHandler(); validateHandler.setNext(loginHandler); loginHandler.setNext(authHandler); validateHandler.doHandler(new Member(loginName, loginPass)); } }
public static void main(String[] args) { MemberService memberService = new MemberService(); memberService.login("cfh", "123456"); }
====================================================================================ide
public abstract class Handler<T> { protected Handler next; public void setNext(Handler next) { this.next = next; } /** * 處理器 * * @param member */ public abstract void doHandler(Member member); public static class Builder<T> { private Handler<T> head; private Handler<T> tail; public Builder<T> addHandler(Handler handler) { // do { if (this.head == null) { this.head = this.tail = handler; } this.tail.setNext(handler); this.tail = handler; // 真正框架中, 若是是雙向鏈表, 會判斷是否已經到了尾部 // } while (false); return this; } public Handler<T> build() { return this.head; } } }
public class ValidateHandler extends Handler { @Override public void doHandler(Member member) { if (StringUtils.isEmpty(member.getLoginName()) || StringUtils.isEmpty(member.getLoginPass())) { System.out.println("用戶名和密碼爲空"); return; } System.out.println("用戶名和密碼不爲空,能夠往下執行"); next.doHandler(member); } }
public class LoginHandler extends Handler { @Override public void doHandler(Member member) { System.out.println("登陸成功!"); member.setRoleName("管理員"); next.doHandler(member); } }
public class MemberService { public void login(String loginName, String loginPass) { Handler.Builder builder = new Handler.Builder(); builder.addHandler(new ValidateHandler()).addHandler(new LoginHandler()).addHandler(new AuthHandler()); builder.build().doHandler(new Member(loginName, loginPass)); } }
public static void main(String[] args) { MemberService memberService = new MemberService(); memberService.login("cfh", "123456"); }
源碼中的運用:性能
javax包中的Filter類方法ui
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
Netty中的this
ChannelPipeline的實現類之一 DefaultChannelPipeline
ChannelHandler的實現類之一 ChannelInboundHandlerspa
優勢:
一、將請求和處理解耦
二、請求處理者(節點對象)只需關注自感興趣的請求進行處理便可,
對於不感興趣的請求, 直接轉發給下一級節點對象;
三、具有鏈式傳遞請求功能, 氫氣發送者無需知曉鏈路結構, 只需等待請求處理結果
四、鏈路結構靈活, 能夠經過改變鏈路結構動態地新增或刪減責任
五、易於擴展新的請求處理類(節點), 符合開閉原則
缺點:
一、責任鏈太長或者處理時間過長, 會影響總體性能
二、若是節點對象存在循環引用時, 會形成死循環, 致使系統崩潰對象