三、责任链模式
本文最后更新于 825 天前,其中的信息可能已经有所发展或是发生改变。

责任链模式

定义

在职责链模式中,多个处理器依次处理同一个请求。一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。

在 GoF 的定义中,一旦某个处理器能处理这个请求,就不会继续将请求传递给后续的处理器了。当然,在实际的开发中,也存在对这个模式的变体,那就是请求不会中途终止传递,而是会被所有的处理器都处理一遍。

实现方式

链表

AbstractHandler

public abstract class AbstractHandler {

    private AbstractHandler nextHandler;

    public void setNextHandler(AbstractHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public void handle() {
        boolean handled = doHandle();
        if (!handled && nextHandler != null) {
            nextHandler.handle();
        }
    }

    protected abstract boolean doHandle();
}

HandlerA

public class HandlerA extends AbstractHandler {
    @Override
    protected boolean doHandle() {
        boolean result = false;
        System.out.println("HandlerA");
        return result;
    }
}

HandlerB

public class HandlerB extends AbstractHandler {
    @Override
    protected boolean doHandle() {
        boolean result = false;
        System.out.println("HandlerB");
        return result;
    }
}

HandlerChain

public class HandlerChain {
    private AbstractHandler head;
    private AbstractHandler tail;

    public HandlerChain addHandler(AbstractHandler handler) {
        if (head == null) {
            head = handler;
            tail = handler;
        } else {
            tail.setNextHandler(handler);
            tail = handler;
        }
        return this;
    }

    public void handle() {
        if (head != null) {
            head.handle();
        }
    }
}

Application

public class Application {
    public static void main(String[] args) {
        final HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA())
             .addHandler(new HandlerB())
             .handle();
    }
}

数组

IHandler

public interface IHandler {
    void handle();
}

HandlerA

public class HandlerA implements IHandler {
    @Override
    public void handle() {
        System.out.println("HandlerA");
    }
}

HandlerB

public class HandlerB implements IHandler {
    @Override
    public void handle() {
        System.out.println("HandlerB");
    }
}

HandlerChain

public class HandlerChain {
    private List<IHandler> chain = Lists.newArrayList();

    public HandlerChain addHandler(IHandler handler) {
        chain.add(handler);
        return this;
    }

    public void handle() {
        chain.forEach(IHandler::handle);
    }
}

Application

public class Application {
    public static void main(String[] args) {
        final HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA())
             .addHandler(new HandlerB())
             .handle();
    }
}

优缺点

  • 你可以控制请求处理的顺序。
  • 单一职责原则。 你可对发起操作和执行操作的类进行解耦。
  • 开闭原则。 你可以在不更改现有代码的情况下在程序中新增处理者。

适用场景

当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式。

该模式能将多个处理者连接成一条链。 接收到请求后, 它会 “询问” 每个处理者是否能够对其进行处理。 这样所有处理者都有机会来处理请求。

当必须按顺序执行多个处理者时, 可以使用该模式。

无论你以何种顺序将处理者连接成一条链, 所有请求都会严格按照顺序通过链上的处理者。

如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。

如果在处理者类中有对引用成员变量的设定方法, 你将能动态地插入和移除处理者, 或者改变其顺序。

实战

@ChainNode:标识责任链节点

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ChainNode {

    /**
     * 所属链名称
     */
    String chain();

    /**
     * 节点名称
     */
    String name() default StrUtil.EMPTY;

    /**
     * 在链中的位置(-1表示末尾)
     */
    int index() default -1;
}
  • 支持多条责任链
  • 支持配置执行顺序

Validate:定义责任链节点的能力

支持多个定义,只有要与之对应的执行器就行

public interface Validate<T> {
    /**
     * 执行校验
     *
     * @param context
     * @author yuyouyang
     * @date 2021/6/3 21:38
     * @version 1.0
     */
    void doValidate(T context);
}
  • 参数和结果都放在context里

ColumnValidate:责任链节点,字段校验

@Component
@ChainNode(chain = ChainConstant.DESIGN_VALIDATE_CHAIN, name = ChainConstant.COLUMN_VALIDATE, index = 1)
public class ColumnValidate implements Validate<Map<String, Object>> {
    @Override
    public void doValidate(Map<String, Object> context) {...}
}

HasExecutedValidate:责任链节点,校验是否已经执行

@Component
@ChainNode(chain = ChainConstant.DESIGN_VALIDATE_CHAIN, name = ChainConstant.HAS_EXECUTED_VALIDATE, index = -1)
public class HasExecutedValidate implements Validate<Map<String, Object>> {
    @Override
    public void doValidate(Map<String, Object> context) {...}
}

ValidateChainExecutor:责任链执行器

public class ValidateChainExecutor{

    private Map<String, List<Validate>> chains = Maps.newHashMap();

    private Map<String, Object> validations;

    public ValidateChainExecutor(Map<String, Object> validations) {
        this.validations = validations;
        init();
    }

    /**
     * 初始化责任链
     *
     * @author yuyouyang
     * @date 2021/6/3 21:36
     * @version 1.0
     */
    private void init() {
        final Class<ChainNode> validateAnnoClass = ChainNode.class;
        validations.values()
                   .forEach(validation -> {
                       final ChainNode anno = validation.getClass()
                                                        .getAnnotation(validateAnnoClass);
                       chains.computeIfAbsent(anno.chain(), v -> new ArrayList<>())
                             .add((Validate) validation);
                   });

        // 排序
        chains.values()
              .forEach(chain -> chain.sort(Comparator.comparingInt(c -> c.getClass()
                                                                         .getAnnotation(validateAnnoClass)
                                                                         .index())));
    }

    @SuppressWarnings("unchecked")
    public <T> void execute(String chain, T context) {
        chains.get(chain)
              .forEach(validation -> validation.doValidate(context));
    }
}
  • 组装责任链
  • 提供执行责任链的方法

ChainConfig:注册责任链

@Configuration
public class ChainConfig {

    @Autowired
    private ApplicationContext applicationContext;

    @Bean
    @ConditionalOnMissingBean
    public ValidateChainExecutor getChainExecutor() {
        return new ValidateChainExecutor(applicationContext.getBeansWithAnnotation(ChainNode.class));
    }
}
  • 注册为bean,使用时注入即可
作者:Yuyy
博客:https://yuyy.info
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇