场景:
在实际开发过程中,成本计算的方式为:先进先出,自定义,月末加权等。那么在实际查询业务我们某一种或多种成本,这时候就可以按照一下的方式解决 if else 问题。
方案:
首先定义一个公共接口|(抽象类)BaseCostOption
,实现类分别是先进先出,自定义,月末加权:FifoCostOption
,CustomCostOption
,MonthAvgCostOption
,工程类:CostOptionFactory
作用初始化和获取实例。
类图:
@Data
public class CommodityCostParam {
// 根据实际业务定义
}
公共接口实现InitializingBean
,为啥?,由于整个项目是依赖Spring
,Bean
的创建是通过Spring
容器来实现,即在项目启动对象就会被初始化好。
public interface BaseCostOption extends InitializingBean {
Map<String, BigDecimal> obtainCostValue(CommodityCostParam commodityCostParam);
}
先进先出业务实现
@Component
@Slf4j
public class FifoCostOption implements BaseCostOption {
private static FifoCostOption FIFO_COST_OPTION;
@Override
public Map<String, BigDecimal> obtainCostValue(CommodityCostParam commodityCostParam) {
// 具体业务实现
log.info(CostValueTypeEnum.FIFO.costDesc);
return Collections.emptyMap();
}
@Override
public void afterPropertiesSet() throws Exception {
FIFO_COST_OPTION = this;
}
public static FifoCostOption getOption() {
return FIFO_COST_OPTION;
}
}
自定义业务实现
@Slf4j
@Component
public class CustomCostOption implements BaseCostOption {
private static CustomCostOption CUSTOM_COST_OPTION;
@Override
public Map<String, BigDecimal> obtainCostValue(CommodityCostParam commodityCostParam) {
// 具体的业务实现
log.info(CostValueTypeEnum.CUSTOM.costDesc);
return Collections.emptyMap();
}
@Override
public void afterPropertiesSet() throws Exception {
CUSTOM_COST_OPTION = this;
}
public static CustomCostOption getOption() {
return CUSTOM_COST_OPTION;
}
}
月末加权业务实现
@Component
@Slf4j
public class MonthAvgCostOption implements BaseCostOption {
private static MonthAvgCostOption MONTHAVG_COST_OPTION;
@Override
public Map<String, BigDecimal> obtainCostValue(CommodityCostParam commodityCostParam) {
// 具体业务实现
log.info(CostValueTypeEnum.MONTH_AVG.costDesc);
return Collections.emptyMap();
}
@Override
public void afterPropertiesSet() throws Exception {
MONTHAVG_COST_OPTION = this;
}
public static MonthAvgCostOption getOption() {
return MONTHAVG_COST_OPTION;
}
}
枚举类
@AllArgsConstructor
@Getter
public enum CostValueTypeEnum {
FIFO("先进先出"),
MONTH_AVG("月末加权"),
CUSTOM("自定义");
public final String costDesc;
}
工厂类承担的职责:初始化实例对象,获取对象实例
public class CostOptionFactory {
static Map<String, BaseCostOption> map;
// 初始化实例对象
static {
map = ImmutableMap.of(
CostValueTypeEnum.Way.FIFO.getKey(), FifoCostOption.getOption(),
CostValueTypeEnum.Way.MONTH_AVG.getKey(), MonthAvgCostOption.getOption(),
CostValueTypeEnum.Way.CUSTOM.getKey(), CustomCostOption.getOption());
}
public static class SingletonHolder {
public static final CostOptionFactory COST_OPTION_FACTORY = new CostOptionFactory();
}
public static CostOptionFactory getCostOptionFactory() {
return SingletonHolder.COST_OPTION_FACTORY;
}
// 获取对象实例
public BaseCostOption getCostStrategy(String costType) {
return map.get(costType);
}
}
单元测试程序
@SpringBootTest
class CostServiceImplTest {
@Test
void obtainCostValue() {
// 如果想在service中调用,在service定义方法,直接调用即可
CommodityCostParam param = new CommodityCostParam();
CostOptionFactory.getCostOptionFactory()
.getCostStrategy(CostValueTypeEnum.MONTH_AVG.name())
.obtainCostValue(param);
}
}
完毕~~~~~~~~~~~~~~~~