侧边栏壁纸
博主头像
Terry

『LESSON 5』

  • 累计撰写 90 篇文章
  • 累计创建 21 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

对于if...else优化的一种方式-选择器

Terry
2022-05-13 / 0 评论 / 0 点赞 / 275 阅读 / 776 字 / 正在检测是否收录...

前言

业务代码中很多地方都存在if()else if()或者if() return if() return的代码,某种程度上可以通过策略模式和责任链模式处理。但是在某些场景下通过设计模式进行整理又显得复杂,所以设计了一套选择器来应对这种情况。

链接

三种设计模式模板

具体代码

public class ContextSelector<C, R> {

    /**
     * 参数
     */
    private C param;

    /**
     * 选择的上下文结果集
     */
    private List<Supplier<Context<C, R>>> contexts;

    /**
     * 默认结果
     */
    private Function<C, R> result;

    private ContextSelector() {
    }

    /**
     * 初始化,无默认返回结果
     *
     * @param param 参数
     * @param <C>   参数类型
     * @param <R>   结果类型
     * @return 选择器
     */
    public static <C, R> ContextSelector<C, R> init(final C param) {
        ContextSelector<C, R> converter = new ContextSelector<>();
        converter.param = param;
        return converter;
    }

    /**
     * 初始化
     *
     * @param param         参数
     * @param defaultResult 默认结果
     * @param <C>           参数类型
     * @param <R>           结果类型
     * @return 选择器
     */
    public static <C, R> ContextSelector<C, R> init(final C param, final Function<C, R> defaultResult) {
        ContextSelector<C, R> converter = new ContextSelector<>();
        converter.param = param;
        converter.result = defaultResult;
        return converter;
    }

    /**
     * 注册选择的上下文
     *
     * @param context 上下文
     * @return 选择器
     */
    public synchronized ContextSelector<C, R> register(Supplier<Context<C, R>> context) {
        if (contexts == null) {
            contexts = new ArrayList<>();
        }
        contexts.add(context);
        return this;
    }

    /**
     * 执行选择器
     *
     * @return 执行结果
     */
    public R execute() {
        List<Supplier<Context<C, R>>> contexts = this.contexts;
        for (final Supplier<Context<C, R>> supplier : contexts) {
            Context<C, R> context = nullSafeGet(supplier);
            if (context == null) {
                continue;
            }
            if (context.condition.test(this.param)) {
                return context.result.apply(this.param);
            }
        }
        return Optional.ofNullable(result).map(result -> result.apply(this.param)).orElse(null);
    }

    /**
     * 执行管道
     *
     * @return 执行结果
     */
    public List<R> pipeline() {
        List<R> result = new ArrayList<>();
        List<Supplier<Context<C, R>>> contexts = this.contexts;
        for (final Supplier<Context<C, R>> supplier : contexts) {
            Context<C, R> context = nullSafeGet(supplier);
            if (context == null) {
                continue;
            }
            if (context.condition.test(this.param)) {
                result.add(context.result.apply(this.param));
            }
        }
        Optional.ofNullable(this.result).map(o -> o.apply(this.param)).ifPresent(result::add);
        return result;
    }


    public static class Context<C, R> {

        /**
         * 条件
         */
        Predicate<C> condition;

        /**
         * 结果
         */
        Function<C, R> result;

        private Context() {
        }

        public Context(final Predicate<C> condition, final Function<C, R> result) {
            this.condition = condition;
            this.result = result;
        }
    }

    private static <C, R> Context<C, R> nullSafeGet(Supplier<Context<C, R>> messageSupplier) {
        return messageSupplier != null ? messageSupplier.get() : null;
    }

}

例子

int param = 3;
// if() return if() return
String result = ContextSelector.init(param, o -> "4")
         .register(() -> new ContextSelector.Context<>(o -> o == 1, o -> "1"))
         .register(() -> new ContextSelector.Context<>(o -> o == 2, o -> "2"))
         .register(() -> new ContextSelector.Context<>(o -> o == 3, o -> "3"))
         .execute();
// if()...if()...
String result = ContextSelector.init(param, o -> "4")
      .register(() -> new ContextSelector.Context<>(o -> o == 1, o -> "1"))
      .register(() -> new ContextSelector.Context<>(o -> o == 2, o -> "2"))
      .register(() -> new ContextSelector.Context<>(o -> o == 3, o -> "3"))
      .pipeline();

可以看出,先创建了Conetxt对象,此对象中插入条件和处理结果,相当于if()和{}中处理信息。然后把此对象注册到Selector中,分别调用execute和pipeline达到if()…if()…和if() return if() return效果。

0

评论区