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

59 阅读3分钟

  • 意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

  • 主要解决:在有多种算法相似的情况下,使用 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;

/**

  • Details determine success.

  • by Liang ZC., Phd@Stanford

  • @author LIANGZHICHENG

  • @date 2019-7-10 15:46

  • @see www.stanford.edu

*/

public class ListUtils {

/**

  • {@param srcList} join {@param joinList} and the {@param srcList} will be distincted.

  • @param srcList

  • @param joinList

*/

public static void joinAndDistinct(List srcList,

List 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

  • @return

*/

public static List unionAndDistinct(List list1,

List 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.*;

/**

  • Details determine success.

  • by Liang ZC., Phd@Stanford

  • @author LIANGZHICHENG

  • @date 2019-8-18 13:56

  • @see 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:::::M7777777777M777M ++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 getUmList(List umUsers,

List faqPrevRecorderUmUsers) {

return ListUtils.unionAndDistinct(umUsers, faqPrevRecorderUmUsers);

}

},

PEND_AUDIT_STEP(1, "待通过审核") {

@Override

public List getUmList(List umUsers,

List faqPrevRecorderUmUsers) {

return faqPrevRecorderUmUsers;

}

},

AUDITING_STEP(2, "审核中") {

@Override

public List getUmList(List umUsers,

List faqPrevRecorderUmUsers) {

return faqPrevRecorderUmUsers;

}

},

PASS_AUDIT_STEP(3, "已通过审核") {

@Override

public List getUmList(List umUsers,

List 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 getUmList(List umUsers,

List faqPrevRecorderUmUsers);

StepEnum(Integer code,

String value) {

this.code = code;

this.value = value;

}

public Integer getCode() {

return code;

}

public String getValue() {

return value;