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。反而每次都需要判断,然后创建不同的策略来执行

 于是可以进行这样改进:

  

方案一:简单的策略工厂(最基本)

这是最直接的改进,将创建策略的逻辑封装到一个工厂类中。

java
// 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

 

 

posted @ 2025-10-24 18:31  也许已没有也许  阅读(6)  评论(0)    收藏  举报