欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

策略模式生产实践

程序员文章站 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