策略模式生产实践
程序员文章站
2022-05-04 08:55:47
需求:根据根据店铺分数确认店铺的活跃状态,但是不同等级的店铺判断条件不同。代码实现包路径:首先定义...
需求:
根据根据店铺分数确认店铺的活跃状态,但是不同等级的店铺判断条件不同。
代码实现
包路径:
运行环境:jdk,spring
外部pom依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
首先定义两个接口:
public interface ScoreStrategy<T, P> {
/**
* 根据分数计算门店活跃状态
*
* @param indicator
* @return
*/
T score(P indicator);
}
public interface ScoreTypeStrategy<T> {
/**
* 策略
*
* @return
*/
T strategy();
}
定义一个抽象类实现两个接口:注意此处使用抽象类是因为没有实现ScoreTypeStrategy接口的 T strategy();
public abstract class AbstractScoreActiveStrategy implements ScoreTypeStrategy<StoreLevelEnum>, ScoreStrategy<StoreActiveEnum, Integer> {
/**
* 用来存储不同的等级对应的店铺分数
*/
List<Pair<StoreActiveEnum, Range<Integer>>> loToHighRange;
/**
* 通过构造方法注入门店分数对应的门店活跃状态
*/
public AbstractScoreActiveStrategy(List<Pair<StoreActiveEnum, Range<Integer>>> loToHighRange) {
Assert.notEmpty(loToHighRange, "loToHighRange not null!");
this.loToHighRange = loToHighRange;
}
/**
* 根据店铺分数
*
* @param storeScore
* @return
*/
@Override
public StoreActiveEnum score(Integer storeScore) {
return loToHighRange.stream()
.filter(pair -> pair.getValue().contains(storeScore)) //核心逻辑:判断分数是否在该Range范围内
.findFirst()//正常只有一个,因此只取一个
.map(Pair::getKey).orElse(null); //将门店分数对应的门店活跃状态返回
}
}
定义四个不同等级门店的根据门店分数获取门店活跃状态的策略类:
注意每个门店都加上了@Service注解,也就是说我们将这些策略类交给spring来管理
@Service
public class SLevelActiveStrategy extends AbstractScoreActiveStrategy {
/**
* A等级的店铺:不同的店铺等级分对应的店铺活跃状态
*/
public SLevelActiveStrategy() {
super(Arrays.asList(
Pair.of(StoreActiveEnum.ACTIVE, Range.closed(0, 10)),
Pair.of(StoreActiveEnum.SILENT, Range.closed(11, 15)),
Pair.of(StoreActiveEnum.DEEP_SILENT, Range.closed(16, 30)),
Pair.of(StoreActiveEnum.DECLINE, Range.greaterThan(30))
));
}
@Override
public StoreLevelEnum strategy() {
return StoreLevelEnum.S;
}
}
@Service
public class ALevelActiveStrategy extends AbstractScoreActiveStrategy {
/**
* A等级的店铺:不同的店铺等级分对应的店铺活跃状态
*/
public ALevelActiveStrategy() {
super(Arrays.asList(
Pair.of(StoreActiveEnum.ACTIVE, Range.closed(0, 15)),
Pair.of(StoreActiveEnum.SILENT, Range.closed(16, 30)),
Pair.of(StoreActiveEnum.DEEP_SILENT, Range.closed(31, 45)),
Pair.of(StoreActiveEnum.DECLINE, Range.greaterThan(45))
));
}
@Override
public StoreLevelEnum strategy() {
return StoreLevelEnum.A;
}
}
@Service
public class BLevelActiveStrategy extends AbstractScoreActiveStrategy {
/**
* A等级的店铺:不同的店铺等级分对应的店铺活跃状态
*/
public BLevelActiveStrategy() {
super(Arrays.asList(
Pair.of(StoreActiveEnum.ACTIVE, Range.closed(0, 15)),
Pair.of(StoreActiveEnum.SILENT, Range.closed(16, 30)),
Pair.of(StoreActiveEnum.DEEP_SILENT, Range.closed(31, 45)),
Pair.of(StoreActiveEnum.DECLINE, Range.greaterThan(45))
));
}
@Override
public StoreLevelEnum strategy() {
return StoreLevelEnum.A;
}
}
@Service
public class CLevelActiveStrategy extends AbstractScoreActiveStrategy {
/**
* A等级的店铺:不同的店铺等级分对应的店铺活跃状态
*/
public CLevelActiveStrategy() {
super(Arrays.asList(
Pair.of(StoreActiveEnum.ACTIVE, Range.closed(0, 30)),
Pair.of(StoreActiveEnum.SILENT, Range.closed(31, 45)),
Pair.of(StoreActiveEnum.DEEP_SILENT, Range.closed(46, 60)),
Pair.of(StoreActiveEnum.DECLINE, Range.greaterThan(60))
));
}
@Override
public StoreLevelEnum strategy() {
return StoreLevelEnum.C;
}
}
最后是外部调用的接口:
@Service
public class StoreActiveService {
private Map<StoreLevelEnum, AbstractScoreActiveStrategy> activeStrategyMap;
/**
* 通过构造方法将策略注入进来
*
* @param activeStrategies
*/
public StoreActiveService(List<AbstractScoreActiveStrategy> activeStrategies) {
this.activeStrategyMap = activeStrategies.stream().collect(Collectors.toMap(ScoreTypeStrategy::strategy, Function.identity()));
}
/**
* 根据店铺的分数获取店铺的活跃状态
*
* @param storeLevelEnum
* @param storeScore
* @return
*/
public StoreActiveEnum calculateStoreActive(StoreLevelEnum storeLevelEnum, Integer storeScore) {
if (Objects.isNull(storeLevelEnum) || Objects.isNull(storeScore)) {
return null;
}
AbstractScoreActiveStrategy strategy = activeStrategyMap.get(storeLevelEnum);
if (Objects.nonNull(strategy)) {
return strategy.score(storeScore);
}
return null;
}
}
当外部使用的时候直接将StoreActiveService导入,调用calculateStoreActive()即可。
代码中使用到的枚举:
@Getter
public enum StoreActiveEnum {
/**
* 店铺状态
*/
ACTIVE(1, "活跃门店"),
SILENT(2, "沉默门店"),
DEEP_SILENT(3, "深度沉默门店"),
DECLINE(4, "衰退门店");
private int value;
private String name;
StoreActiveEnum(int value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return this.value;
}
public String getName() {
return this.name;
}
private static Map<Integer, StoreActiveEnum> initMap = new HashMap<>();
static {
Stream.of(StoreActiveEnum.values()).forEach(enumValue -> {
initMap.put(enumValue.getValue(), enumValue);
});
}
public static StoreActiveEnum findByValue(Integer value) {
return initMap.get(value);
}
}
@Getter
public enum StoreLevelEnum {
/**
* 门店等级
*/
S(1, "金牌"),
A(2, "银牌"),
B(3, "银牌"),
C(4, "铜牌");
private int value;
private String name;
StoreLevelEnum(int value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return this.value;
}
public String getName() {
return this.name;
}
private static Map<Integer, StoreLevelEnum> initMap = new HashMap<>();
static {
Stream.of(StoreLevelEnum.values()).forEach(enumValue -> {
initMap.put(enumValue.getValue(), enumValue);
});
}
public static StoreLevelEnum findByValue(Integer value) {
return initMap.get(value);
}
}
本文地址:https://blog.csdn.net/weixin_41891854/article/details/107368358
下一篇: Mybatis-Plus Sql 注入器