前言
日常开发过程中,我们写业务代码写的最多的可能就是if…else、else…if,有的时候我们确实要写,但是可以在能不写的时候尽量避免去写它,从而提升自己写代码的优雅性,记得还早以前,那时候我才刚做开发看一些别人写的代码,通常觉得实现一个逻辑为何如此复杂,要加好几个类什么handler、Strategy才能实现,不如一个if else 直接实现逻辑,现在想想当时确实年轻。
基本策略模式
通过定义通用的Strategy接口,不同的业务类实现Strategy,重写自己的业务逻辑,然后通过Context环境类去判断具体走哪个策略方法,虽然解决的通过type去做判断,解决if..else和代码的耦合度,但是依旧显得十分笨重。
Strategy接口
public interface Strategy {
//保费计算基本方法
Double premiumFormula(Double cost);
}
策略类
//孩子费用计算
public class ChildrenStrategy implements Strategy { @Override public Double premiumFormula(Double cost) {
//子女费用减半
cost =cost*0.5; return cost; } }
//父母费用计算
public class ParentStrategy implements Strategy{ @Override public Double premiumFormula(Double cost) {
//父母八折
cost =cost*0.8; return cost; } }
环境类
public class Context { private Strategy strategy; public Content(String type) { if (type==“children”){ this.strategy=new ChildrenStrategy(); } if (type==“parent”){ this.strategy = new ParentStrategy(); } }
//环境类方法计算方法
public Double contextMethod(Double cost){ return strategy.premiumFormula(cost); } }
测试方法
public class StrategyTest { public static void main(String[] args) { System./out/.println(“子女保费计算金额:”+new
Content(“children”).contextMethod(100.0));
System./out/.println(“父母保费计算金额:”+new Content(“parent”).contextMethod(100.0)); } }
枚举策略模式
通过在枚举类里定义公共抽象方法,不同的枚举策略重写公共抽象方法时间不同业务逻辑
StrategyEnum策略枚举类
public enum StrategyEnum {
ChildrenStrategy {
@Override
public Double premiumFormula(Double cost) {
cost =cost*0.5;
return cost;
}
},
ParentStrategy {
@Override
public Double premiumFormula(Double cost) {
cost =cost*0.8;
return cost;
}
};
//计算方法
public abstract Double premiumFormula(Double cost);
}
测试方法
由此可见,枚举策略的方式更加轻便,可以不同创建环境类来承担调用的介质,直接通过一个枚举策略类即可实现不同的业务逻辑,只需要传入不同的枚举类型。
public static void main(String[] args) {
StrategyEnum strategyEnum =StrategyEnum.valueOf(StrategyEnum.ChildrenStrategy.name());
Double aDouble = strategyEnum.premiumFormula(new Double(2.0));
System.out.println("孩子金额计算结果:"+new BigDecimal(aDouble));
}
工厂策略模式
业务类实现策略接口,通过@Service注解将此类交给Spring Factory来管理进行初始化,类名作为key,会将策略类放到一个map集合里面。
@Service("ParentStrategy")
public class ParentStrategy implements Strategy{
@Override
public Double premiumFormula(Double cost) {
cost =cost*0.8;
return cost;
}
}
业务servcie通过调用已经在Spring IOC容器进行初始化后的策略bean,进行业务逻辑实现。
@Service
public class ExcuteService {
@Resource
private Map<String, Strategy> strategyMap;
public BigDecimal getCalculateAmount(String type) throws IllegalAccessException {
if (!strategyMap.containsKey(type)){
throw new IllegalAccessException("type 不存在");
}
Strategy strategy = strategyMap.get(type);
Double aDouble = strategy.premiumFormula(new Double(2.0));
return new BigDecimal(aDouble);
}
}
三种策略模式总结
- 基本策略模式:虽说能实现代替if…else,根据策略类实现不一样的业务逻辑,但是整体策略模式显的非常笨重,不是很灵活,已经不推荐使用这种设计模式开发了。
- 枚举策略模式:简单轻便,对于简单的策略业务逻辑,非常推荐使用,如有业务逻辑变动只需要更改枚举类即可。
- 工厂策略模式:适用于相对比较复杂的业务场景,通过工厂模式加载策略类,更加适合在Spring体系下进行开发,易拓展、更加灵活。
最后啰嗦一下,设计模式是帮助我们在写代码的时候,让代码在解耦、灵活、可扩展、删繁就简的基础上,让代码的实现更加优雅,切勿为了单纯使用设计模式而画蛇添足。