java设计模式--策略模式
如果这边文章能给你带来帮助,不胜荣幸。如果有错误也请批评指正,一起学习,共同进步;
java有很多设计模式,这篇写策略模式,策略模式就是根据不同的需求选择不同的代码块,用来替换if else等操作的。不是消除if else而是对if else进行管理。降低代码的耦合
假如我现在有一个需求,通过不同的方式上西天。根据前台传递来的参数不同,用不同的方式上西天。可以这么写
@Override public void toHitjaps(Integer hitType) { HitContext hitContext; if(hitType==1){ //通过西伯利亚种土豆建设社会主义上西天 }else if(hitType==2){ //通过小男孩洗头上西天 }else if(hitType==3){ //通过地雷上西天 }else{ System.out.println("其他情况!!!!!!!!!!"); } }
但是这样有一个弊端,就是当我开辟了一条新的上西天的道路的时候,我需要在这里进行else if()代码的叠加。这个时候建议使用策略模式来处理
策略模式主要有三个模块,一个是 策略接口 一个是策略接口的具体实现 另一个是策略模式的上下文处理
策略接口就是抽取上西天的方法
具体实现就是多种具体的上西天的方法实现
上下文就是使用策略模式的环境
具体分别如下:
策略接口(抽取一个公共的接口)
public interface HitStrategy { public void hitJaps(); }
具体的几个实现接口的实现类
@Component public class LandmineHitStrategyImpl implements HitStrategy { @Override public void hitJaps() { //处理的业务逻辑 System.out.println("用地雷超度"); } }
@Component public class NucleusHitStrategyImpl implements HitStrategy { @Override public void hitJaps() { System.out.println("用小男孩和胖子给洗头"); } }
@Component public class SiberiaHitStrategyImpl implements HitStrategy { @Override public void hitJaps() { System.out.println("送去西伯利亚建设社会主义"); } }
还有一个就是策略上下文了
public class HitContext { HitStrategy hitStrategy; //构造函数,要你使用哪个具体的实现 public HitContext(HitStrategy hitStrategy){ this.hitStrategy = hitStrategy; } public void hit(){ this.hitStrategy.hitJaps(); } }
这个是简单的,完全没有发挥策略模式的应用如下:
@Override public void toHitjaps(Integer hitType) { HitContext hitContext; //送小日子去西伯利亚挖土豆建设社会主义 if(hitType==1){ hitContext = new HitContext(new SiberiaHitStrategyImpl()); hitContext.hit(); //小男孩洗头 }else if(hitType==2){ hitContext = new HitContext(new NucleusHitStrategyImpl()); hitContext.hit(); //地雷拌饭 }else if(hitType==3){ hitContext = new HitContext(new LandmineHitStrategyImpl()); hitContext.hit(); //其他 }else{ System.out.println("其他情况!!!!!!!!!!"); } }
这样这种写法不仅没有消除if else。反而每次都需要判断,然后创建不同的策略来执行
于是可以进行这样改进:
方案一:简单的策略工厂(最基本)
这是最直接的改进,将创建策略的逻辑封装到一个工厂类中。
// 1. 策略工厂
public class DiscountStrategyFactory { public static HitStrategy getStrategy(Integer hitType) { if (1==hitType) { return new LandmineHitStrategyImpl(); } else if (2==hitType) { return new NucleusHitStrategyImpl(); } else{ return new SiberiaHitStrategyImpl(); } } }
// 2. 业务代码变得干净
@Override public void toHitjaps(Integer hitType) { HitStrategy strategy = DiscountStrategyFactory.getStrategy(hitType); strategy.hitJaps(); }
优点: 业务代码中的 if/else 消失了,创建逻辑被集中。但是还是有if else .总体来说比上一版要好
方案二:使用 Map 注册策略(消除 if/else)
同样在策略工厂里面提前把策略都准备好,等这调用就可以了!
private static final Map<String, HitStrategy> STRATEGIES = new HashMap<>(); // 初始化时注册所有策略 static { STRATEGIES.put("1", new LandmineHitStrategyImpl()); STRATEGIES.put("2", new NucleusHitStrategyImpl()); STRATEGIES.put("3", new SiberiaHitStrategyImpl()); } public static HitStrategy getStrategy(Integer hitType) { // 直接通过key从Map中获取,没有if/else! HitStrategy strategy = STRATEGIES.get(String.valueOf(hitType)); return strategy; }
@Override public void toHitjaps(Integer hitType) { HitStrategy strategy = DiscountStrategyFactory.getStrategy(hitType); strategy.hitJaps(); }
这种呢,也是提前写死的,相比较其他两种会好一点
方案三:结合 Spring 框架
就是需要再具体的实现策略的实体类上加上注解,spring会自动注入封装到Map当中
@Component("landmine")
public class LandmineHitStrategyImpl implements HitStrategy {
@Override
public void hitJaps() {
//处理的业务逻辑
System.out.println("用地雷超度jap");
}
}
@Component("nucleus")
public class NucleusHitStrategyImpl implements HitStrategy {
@Override
public void hitJaps() {
System.out.println("用小男孩和胖子给霓虹人洗头");
}
}
@Component("siberia")
public class SiberiaHitStrategyImpl implements HitStrategy {
@Override
public void hitJaps() {
System.out.println("送小日子去西伯利亚建设社会主义");
}
}
// Spring会自动将Bean名作为Key注入 private Map<String, HitStrategy> strategyMap; public HitStrategy getStrategy(String hitType) { HitStrategy strategy = strategyMap.get(hitType); return strategy; }
最后调用的时候只需要这样就可以了
@Autowired private DiscountStrategyFactory factory; @Override public void toHitjaps(String hitType) { HitStrategy strategy = factory.getStrategy(hitType); strategy.hitJaps(); }
在保证质量的前提下,首推最后一种,在时间紧迫的情况下,首推if else

浙公网安备 33010602011771号