是将链中每个节点看做是一个对象, 每一个节点处理的请求均不一样, 且内部自动维护一个下一节点对象。 当一个请求从链式的首端发出时, 会沿着链的路径依次传递给每个节点对象, 直至有对象处理这个请求为止。 属于行为型模式
适用场景:
一、多个对象能够处理同一个请求, 但具体由那个对象处理则在运行时动态决定;
二、在不明确指定接收者的状况下, 向多个对象中的一个提交一个请求
三、可动态指定一组对象处理请求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
优势:
一、将请求和处理解耦
二、请求处理者(节点对象)只需关注自感兴趣的请求进行处理便可,
对于不感兴趣的请求, 直接转发给下一级节点对象;
三、具有链式传递请求功能, 氢气发送者无需知晓链路结构, 只需等待请求处理结果
四、链路结构灵活, 能够经过改变链路结构动态地新增或删减责任
五、易于扩展新的请求处理类(节点), 符合开闭原则
缺点:
一、责任链太长或者处理时间过长, 会影响总体性能
二、若是节点对象存在循环引用时, 会形成死循环, 致使系统崩溃对象