背景
小七最近看代码时发现了以前自己写的一个方法,伪代码如下:
private BigDecimal matchingAlgorithm(String type, BigDecimal totalAmount) {
// 匹配算法
// 个位,四舍五入
if (TypeEnum.HALF_UP.getCode().equals(type)){
}
// 十位,向下取整
else if (TypeEnum.ROUND_FLOOR.getCode().equals(type)){
}
// 十位,向上取整
else if (TypeEnum.ROUND_HALF_EVEN.getCode().equals(type)){
}
return totalAmount;
}
功能很简单通过类型匹配不同的算法。这样写虽然功能实现了,但是想一想其实有更优雅的实现方式。那就是今天的主角策略模式了。
思考过程
同大多数其它模式一样,我们首先也需要抽象出一个顶级接口或者父类。这里我们定义一个接口——算法策略
public interface AlgorithmStrategy {
/**
* 创造策略
*/
void creatStrategy();
}
定义2个算法子类,分别实现它
向下取整策略
public class RoundDownStrateg implements AlgorithmStrategy{
@Override
public void creatStrategy() {
System.out.println("执行策略:向下取整");
}
}
四舍五入策略
public class RoundHalfUpStrategy implements AlgorithmStrategy{
@Override
public void creatStrategy() {
System.out.println("执行策略:四舍五入");
}
}
激活类
public class AlgorithmStrategyActive {
/**
* 算法策略
*/
private AlgorithmStrategy algorithmStrategy;
/**
* 构造方法
*
* @param algorithmStrategy 算法策略
*/
public AlgorithmStrategyActive(AlgorithmStrategy algorithmStrategy) {
this.algorithmStrategy = algorithmStrategy;
}
/**
* 执行 - 调用的是子类自己的实现
*/
public void execute(){
algorithmStrategy.creatStrategy();
}
}
测试类
public class Test {
public static void main(String[] args) {
AlgorithmStrategyActive strategyActive = matchingAlgorithm("roundDown");
strategyActive.execute();
}
private static AlgorithmStrategyActive matchingAlgorithm(String type) {
AlgorithmStrategyActive strategy = null;
// 四舍五入
if ("roundHalfUp".equals(type)){
// 注册四舍五入策略
strategy = new AlgorithmStrategyActive(new RoundHalfUpStrategy());
}
// 向下取整
else if ("roundDown".equals(type)){
// 注册向下取整策略
strategy = new AlgorithmStrategyActive(new RoundDownStrateg());
}
return strategy;
}
}
执行结果
结合工厂模式优化
这样我们第一版重构就OK了,但是虽然使用了策略模式,但是我们并没有消除代码中的if-else。为什么没有消除判断呢?因为我们创建对象的时候,需要明确是哪个对象才能进行创建,所以我们可以把创建对象的这个工作交给工厂去处理(工厂模式传送门)。
接下来请出咱们的工厂类
public class AlgorithmStrategyFactory {
/**
* 算法策略放入map中
*/
private static Map<String,AlgorithmStrategy> ALGORITHM_STRATEGY_MAP = new HashMap<String, AlgorithmStrategy>(16);
/**
* 类加载的时候就进行初始化
*/
static {
ALGORITHM_STRATEGY_MAP.put("roundHalfUp",new RoundHalfUpStrategy());
ALGORITHM_STRATEGY_MAP.put("roundDown",new RoundDownStrateg());
}
/**
* 得到算法策略
* 注:这里的null可以创建一个空策略,避免空指针异常,作者很懒,就不实现了,哈哈
* @param strategyKey 策略key
* @return {@link AlgorithmStrategy}
*/
public static AlgorithmStrategy getAlgorithmStrategy(String strategyKey){
return strategyKey==null?null:ALGORITHM_STRATEGY_MAP.get(strategyKey);
}
}
测试类
public class Test {
public static void main(String[] args) {
AlgorithmStrategyActive strategyActive = matchingAlgorithm("roundDown");
strategyActive.execute();
}
private static AlgorithmStrategyActive matchingAlgorithm(String type) {
return new AlgorithmStrategyActive(AlgorithmStrategyFactory.getAlgorithmStrategy(type));
}
}
结果
总结
工作中单单只用到一种设计模式的情况很少,一般都要根据业务需求做出调整,所以一定要多学习。加油吧,撸码人~