职责链模式定义是把一个请求传递给多个对象来处理,这些对象都放在一条链上,以实现发送和接受解耦。GoF的《设计模式》中英文定义如下:
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
1.下面看一种最简单的职责链模式。先定义一个处理接口
public interface Handler { void handle(String event); }
然后定义2个处理实现类
public class HandlerA implements Handler{ @Override public void handle(String event) { System.out.println("handler A handle, event:" + event); } } public class HandlerB implements Handler{ @Override public void handle(String event) { System.out.println("handler B handle, event:" + event); } }
定义职责链类
public class HandlerChain { private List<Handler> handlers = new ArrayList<>(5); public void addHandler(Handler handler){ handlers.add(handler); } public void handle(String event){ handlers.forEach(r -> r.handle(event)); } }
再加上一个测试类:
public class TestChain { public static void main(String[] args){ HandlerChain handlerChain = new HandlerChain(); handlerChain.addHandler(new HandlerA()); handlerChain.addHandler(new HandlerB()); handlerChain.handle("test event"); } }
上面就是一个非常简单的职责链模式的实现。这个实现的使用有很多场景,比如我们对一篇文章进行敏感词过滤,过滤内容包括*、涉黄等词汇,我们可以写几个过滤器分别过滤掉敏感词。
2.上面的职责链模式实现非常简单,但是它更适用于所有的处理类都进行处理的场景。但是如果现在有一种场景,职责链中只要有一个处理类处理成功就不再继续往下传,该怎么实现呢?这种情况就需要对Handler做一些控制,用一个抽象类来封装next指针和对next指针的调用,看如下代码:
public interface Handler1 { void handle(String event); void setNext(Handler1 handler); } public abstract class AbstractHandler1 implements Handler1{ public Handler1 next; @Override public void setNext(Handler1 handler){ this.next = handler; } @Override public void handle(String event) { boolean result = doHandle(event); if(!result && hasNext()){ next.handle(event); } } protected boolean hasNext(){ return this.next != null; } public abstract boolean doHandle(String event); }
public class HandlerC extends AbstractHandler1{ @Override public boolean doHandle(String event) { System.out.println("handler C handle, event:" + event); return false; } }
public class HandlerD extends AbstractHandler1{ @Override public boolean doHandle(String event) { System.out.println("handler D handle, event:" + event); return false; } }
再看测试类,
public class TestChain { public static void main(String[] args){ HandlerChain1 handlerChain1 = new HandlerChain1(); handlerChain1.handle(); } }
3.mybatis中的责任链
mybatis中的责任链使用了注解的方式来识别handler类,内部并没有实现,只是预留出接口。
public interface Interceptor { Object intercept(Invocation invocation) throws Throwable; Object plugin(Object target); void setProperties(Properties properties); }
注解接口如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Intercepts { Signature[] value(); }
责任链类:
public class InterceptorChain { private final List<Interceptor> interceptors = new ArrayList<>(); public Object pluginAll(Object target) { for (Interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; } public void addInterceptor(Interceptor interceptor) { interceptors.add(interceptor); } public List<Interceptor> getInterceptors() { return Collections.unmodifiableList(interceptors); } }
在实例化Executor、ParameterHandler、ResultSetHandler、StatementHandler这4个对象时,把这4个对象植入到责任链中,然后用处理类对这些对象做一些操作。
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) { ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql); parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler); return parameterHandler; } public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) { ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds); resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler); return resultSetHandler; } public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql); statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler); return statementHandler; } public Executor newExecutor(Transaction transaction) { return newExecutor(transaction, defaultExecutorType); } public Executor newExecutor(Transaction transaction, ExecutorType executorType) { executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; if (ExecutorType.BATCH == executorType) { executor = new BatchExecutor(this, transaction); } else if (ExecutorType.REUSE == executorType) { executor = new ReuseExecutor(this, transaction); } else { executor = new SimpleExecutor(this, transaction); } if (cacheEnabled) { executor = new CachingExecutor(executor); } executor = (Executor) interceptorChain.pluginAll(executor); return executor; }
源码地址:https://github.com/jinjunzhu/design-pattern.git
欢迎关注个人公众号,共同学习进步