我从公司项目中学到的策略模式

100 阅读1分钟

前言

前几天接到一个打印需求,我翻看项目中现有的打印需求案例时,无意中发现了同事使用的策略模式实现。出于兴趣,我仔细研究了一下他的实现方式。接下来是我对他实现方式的一些理解和总结。

正文

首先,他根据传入的类型,获取到对应的方法:

text.png

//Controller根据 所需数据类型 CustomsDataTypeEnum、 对账主记录id businessMappingId 去查询 所需数据
Function<String,Map<String, Object>> result=dataTypeMap.get(customsDataTypeEnum.getType());

然后根据客户ID,通过infoCustomer.getCustomerType()获取客户类型,再通过getStrategy(infoCustomer.getCustomerType())拿到对应的Bean的名称,在通过map拿到Bean,调用相应的方法。

public enum CustomerTypeEnum {


    GENERAL(0,"测试1","generalCustomerStrategyImpl"),
    REN_BAO(1,"测试2","renBaoCustomerStrategyImpl"),
    YUE_NAN(2,"测试3","yueNanCustomerStrategyImpl");

    private final Integer index;// 序号
    private final String name;// 名称
    private final String strategy;// 策略

    /**
     * @param index: 客户类型数字
     * @return String 策略
     * @author fumin-yue
     * @description: 获取策略
     * @dateTime 2023/12/19 19:29
     */
    public static String getStrategy(Integer index) {
        for (CustomerTypeEnum value : CustomerTypeEnum.values()) {
            if (value.getIndex().equals(index)) {
                return value.getStrategy();
            }
        }
        return null;
    }
}

通过Spring的@Autowired注解,将所有实现CustomerStrategy接口的Bean注入到customerStrategyMap中。

@Autowired
private Map<String, CustomerStrategy> customerStrategyMap;

通过客户类型获取对应的策略Bean,并调用其getInvoiceData方法。

//根据客户类型选择策略
InfoCustomer infoCustomer = this.getInfoCustomer(businessMappingId);
return customerStrategyMap.get(getStrategy(infoCustomer.getCustomerType())).getInvoiceData(businessMappingId);

test1.png

这是他的策略上下文和策略的实现类。策略接口中定义了四个方法,具体实现类中的第一个是抽象类,后面的三个实现类都继承了这个抽象类,并通过@Service注解命名Bean,比如@Service("generalCustomerStrategyImpl")。这些实现类实现了下面的四个抽象方法:

ee.png

public abstract Map<String, Object> getAllData(String businessMappingId);

public abstract Map<String, Object> getContractData(String businessMappingId);

public abstract Map<String, Object> getBoxData(String businessMappingId);

public abstract Map<String, Object> getInvoiceData(String businessMappingId);