23种设计模式——策略模式

一、策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

二、介绍

  • 意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
  • 主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
  • 何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
  • 如何解决:将这些算法封装成一个一个的类,任意地替换。
  • 关键代码:实现同一个接口。
  • 应用实例:
    • 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。
    • 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
    • 3、JAVA AWT 中的 LayoutManager。
  • 优点:
    • 1、算法可以自由切换。
    • 2、避免使用多重条件判断。
    • 3、扩展性良好。
  • 缺点:
    • 1、策略类会增多。
    • 2、所有策略类都需要对外暴露。
  • 使用场景:
    • 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
    • 2、一个系统需要动态地在几种算法中选择一种。
    • 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
  • 注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

三、列表工具类

1、对两个列表去重并合并。

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <code>Details determine success.</code>
 * by Liang ZC., Phd@Stanford
 *
 * @author LIANGZHICHENG
 * @date 2019-7-10 15:46
 * @see http://www.stanford.edu
 */
public class ListUtils {

    /**
     * {@param srcList} join {@param joinList} and the {@param srcList} will be distincted.
     *
     * @param srcList
     * @param joinList
     */
    public static <T> void joinAndDistinct(List<T> srcList,
                                           List<T> joinList) {

        if (CollectionUtils.isEmpty(srcList) && CollectionUtils.isEmpty(joinList)) {
            return;
        }

        LinkedHashSet tmpSet = Sets.newLinkedHashSet();

        tmpSet.addAll(srcList);

        if (CollectionUtils.isNotEmpty(joinList)) {
            tmpSet.addAll(joinList);
        }

        srcList.clear();
        srcList.addAll(tmpSet);
    }

    /**
     * Union two list and distinct .
     *
     * @param list1
     * @param list2
     * @param <T>
     * @return
     */
    public static <T> List<T> unionAndDistinct(List<T> list1,
                                               List<T> list2) {

        return org.apache.commons.collections4.ListUtils
                .union(list1, list2)
                .stream()
                .distinct()
                .collect(Collectors.toList());

    }

}

四、使用枚举类实现策略模式

import com.google.common.collect.ImmutableMap;
import com.pingan.lcloud.ai.knowledgeBase.v2.common.ListUtils;
import com.pingan.lcloud.ai.knowledgeBase.v2.common.enums.FaqStepEnum;
import com.pingan.lcloud.ark.log.LoggerUtil;

import java.lang.annotation.Native;
import java.util.*;

/**
 * <code>Details determine success.</code>
 * by Liang ZC., Phd@Stanford
 *
 * @author LIANGZHICHENG
 * @date 2019-8-18 13:56
 * @see http://www.stanford.edu
 */
public enum StepEnum {
    /*
     *           N777777777NO
     *         N7777777777777N
     *        M777777777777777N
     *        *N877777777D77777M
     *       N M77777777ONND777M
     *       MN777777777NN  D777
     *     N7ZN777777777NN ~M7778
     *    N777777777777MMNN88777N
     *    N777777777777MNZZZ7777O
     *    DZN7777O77777777777777
     *     N7OONND7777777D77777N
     *      8*M++++?N???$77777$
     *       M7++++N+M77777777N
     *        N77O777777777777$                              M
     *          DNNM$$$$777777N                              D
     *         N*N:=N$777N7777M                             NZ
     *        77Z::::N777777777                          ODZZZ
     *       77N::::::N77777777M                         NNZZZ$
     *     $777:::::::77777777MN                        ZM8ZZZZZ
     *     777M::::::Z7777777Z77                        N++ZZZZNN
     *    7777M:::::M7777777$777M                       $++IZZZZM
     *   M777$:::::N777777*M7777M                       +++++ZZZDN
     *     NN$::::::7777$*M777777N                      N+++ZZZZNZ
     *       N::::::N:7*O:77777777                      N++++ZZZZN
     *       M::::::::::::N77777777+                   +?+++++ZZZM
     *       8::::::::::::D77777777M                    O+++++ZZ
     *        ::::::::::::M777777777N                      O+?D
     *        M:::::::::::M77777777778                     77=
     *        D=::::::::::N7777777777N                    777
     *       INN===::::::=77777777777N                  I777N
     *      ?777N========N7777777777787M               N7777
     *      77777*D======N77777777777N777N?         N777777
     *     I77777$$*N7===M$$77777777$77777777*MMZ77777777N
     *      $$$$$$$$$$*NIZN$$$$$$$$*M$$7777777777777777ON
     *       M$$$$$$$*M    M$$$$$$$*N=N$$$$7777777$$*ND
     *      O77Z$$$$$$$     M$$$$$$$*MNI==*DNNNNM=~N
     *   7 :N MNN$$$*M$      $$$777$8      8D8I
     *     NMM.:7O           777777778
     *                       7777777MN
     *                       M NO .7:
     *                       M   :   M
     *                            8
     */

    // Constant matcher factory methods

    ALL_STEP(0, "全部") {
        @Override
        public List<String> getUmList(List<String> umUsers,
                                      List<String> faqPrevRecorderUmUsers) {

            return ListUtils.unionAndDistinct(umUsers, faqPrevRecorderUmUsers);
        }
    },

    PEND_AUDIT_STEP(1, "待通过审核") {
        @Override
        public List<String> getUmList(List<String> umUsers,
                                      List<String> faqPrevRecorderUmUsers) {

            return faqPrevRecorderUmUsers;
        }
    },

    AUDITING_STEP(2, "审核中") {
        @Override
        public List<String> getUmList(List<String> umUsers,
                                      List<String> faqPrevRecorderUmUsers) {

            return faqPrevRecorderUmUsers;
        }
    },

    PASS_AUDIT_STEP(3, "已通过审核") {
        @Override
        public List<String> getUmList(List<String> umUsers,
                                      List<String> faqPrevRecorderUmUsers) {

            return umUsers;
        }
    };

    /**
     * {@code STEP_MAP} include all step enum and isn`t change.
     */
    @Native private static final Map<Integer, StepEnum> STEP_MAP = ImmutableMap.of(
            ALL_STEP.getCode(), ALL_STEP,
            PEND_AUDIT_STEP.getCode(), PEND_AUDIT_STEP,
            AUDITING_STEP.getCode(), AUDITING_STEP,
            PASS_AUDIT_STEP.getCode(), PASS_AUDIT_STEP
    );

    private Integer code;

    private String value;

    /**
     * Return um information list
     *
     * @param umUsers
     * @param faqPrevRecorderUmUsers
     * @return
     */
    public abstract List<String> getUmList(List<String> umUsers,
                                           List<String> faqPrevRecorderUmUsers);

    StepEnum(Integer code,
             String value) {
        this.code = code;
        this.value = value;
    }

    public Integer getCode() {
        return code;
    }

    public String getValue() {
        return value;
    }

    /**
     * Return um information list by {@param step} , and the {@param step} must in {@link FaqStepEnum}.
     *
     * @param umUsers
     * @param faqPrevRecorderUmUsers
     * @param step
     * @return
     */
    public static List<String> getUmListByStep(List<String> umUsers,
                                               List<String> faqPrevRecorderUmUsers,
                                               Integer step) {

        if (Objects.isNull(step)) {
            LoggerUtil.warn("step is null.");
            return Collections.emptyList();
        }

        return STEP_MAP.get(step).getUmList(umUsers, faqPrevRecorderUmUsers);
    }

    public static void main(String[] args) {
        
        List<String> a = Arrays.asList("a");
        List<String> b = Arrays.asList("b");
        Integer step = 1;
        System.out.println(StepEnum.AUDITING_STEP.getUmList(a, b));
        System.out.println(StepEnum.ALL_STEP.getUmList(a, b));
        System.out.println(StepEnum.PEND_AUDIT_STEP.getUmList(a, b));
        System.out.println(StepEnum.PASS_AUDIT_STEP.getUmList(a, b));
        System.out.println(StepEnum.getUmListByStep(a, b, step));

    }
}

四、输出结果

[b]
[a, b]
[b]
[a]
[b]

关注我的技术公众号《漫谈人工智能》,每天推送优质文章

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两只橙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值