責任鏈模式

是將鏈中每個節點看做是一個對象, 每一個節點處理的請求均不一樣, 且內部自動維護一個下一節點對象。
當一個請求從鏈式的首端發出時, 會沿着鏈的路徑依次傳遞給每個節點對象, 直至有對象處理這個請求爲止。
屬於行爲型模式        

適用場景:
        一、多個對象能夠處理同一個請求, 但具體由那個對象處理則在運行時動態決定;
        二、在不明確指定接收者的狀況下, 向多個對象中的一個提交一個請求
        三、可動態指定一組對象處理請求
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

優勢:
    一、將請求和處理解耦
    二、請求處理者(節點對象)只需關注自感興趣的請求進行處理便可, 
        對於不感興趣的請求, 直接轉發給下一級節點對象;
    三、具有鏈式傳遞請求功能, 氫氣發送者無需知曉鏈路結構, 只需等待請求處理結果
    四、鏈路結構靈活, 能夠經過改變鏈路結構動態地新增或刪減責任
    五、易於擴展新的請求處理類(節點), 符合開閉原則
缺點:
    一、責任鏈太長或者處理時間過長, 會影響總體性能
    二、若是節點對象存在循環引用時, 會形成死循環, 致使系統崩潰對象

相關文章
相關標籤/搜索