在代码编写的过程中经常会遇到大量使用if-else的情况,但是太多的if-else会使代码变的臃肿并且难以理解,因此使用策略模式进行编码对if-else进行优化,避免臃肿。

平常经常碰到的代码:

假设设计一个颜色类,可以动态的改变颜色 ```java public class ColorStrategy{ private String color; //车辆颜色 public void getColor(String color) { if (“black”.equals(color)) { System.out.println(“我是黑色”); } else if (“blue”.equals(color)) { System.out.println(“我是蓝色”); } else if (“red”.equals(color)) { System.out.println(“我是红色”); } } }


这种情况下如果只是少数并且镶套不多的代码还可以容易理解,但是每当要添加新的else,代码就会变得臃肿并且要修改已有的代码,这就违背了对修改关闭对扩展开放的设计原则,这种情况下就引出了策略模式。

#### 类图
![](https://s2.ax1x.com/2019/11/27/Qpg2wR.png)

那么如何修改代码使if-else减少呢?
我们可以把每一段else中的语句当做是一个方法。
为每一个要拿来做判断的条件建一个类来实现一个方法。

为了使扩展开放,我们将方法抽象为接口,并让类实现

```java
public interface Color{
    public void checkColor();
}

将if中的具体实现放入接口实现类中 ```java class Black implements Color { @Override public void checkColor() { System.out.println(“我是黑色”); } }

class Blue implements Color{ public void checkColor(){ System.out.println(“我是蓝色”); } }

class Red implements Color { @Override public void checkColor() { System.out.println(“我是红色”); } }


并定义一个策略类根据传入的类判断执行的方法
```java
    class ColorStrategy {
        private Color color;

        public void setColor(Color color) {
            this.color = color;
        }

        void getColor() {
            color.checkColor();
        }
    }

客户端调用

public class client{
    public static void main(String[] args) {
            //如果逻辑简单的话也可以直接用new Black().doSomeThing();
            //循环的话使用List<ColorStrategy> colorList = new ArrayList<>();
            //根据实际情况使用反射
            ColorStrategy colorStrategy = new ColorStrategy();
            colorStrategy.setColor(new Black());
            colorStrategy.getColor();
            
            colorStrategy.setColor(new Red());
            colorStrategy.getColor();
        }
}

会输出如下结果:

我是黑色 我是红色

这样一来哪怕以后增加更多的else也只是新建一个类而不需要修改之前的代码,通过类的增加来维护代码的易懂性,同样通过策略模式也能很好的避免多重镶套的if-else。

下面我们介绍一个实际开发中的使用:

避免臃肿的if else语句

业务场景:

我们有“天、周、月”这三种粒度类型,根据客户端给的粒度取计算两个时间相差的“天、周、月”。例如:当粒度是“周”,那么客户端就会传入两个以周为度量的时间,计算两个时间相差几周。

优化的原因:

为了避免重读的使用if else ,并且降低系统的耦合,方便今后的扩展。我们将采用策略模式进行优化处理。

1、创建粒度的枚举类GranularityEnum:

public enum GranularityEnum {

    DAY(0, "天"),
    WEEK(1, "周"),
    MONTH(2,"月");
    
    private int value;
    private String description;

    private GranularityEnum(int value, String description) {            
        this.value = value;
        this.description = description;
    }

    public int value() {
        return value;
    }

    public String description() {
        return description;
    }

    public static GranularityEnum valueOf(int value) {
        for(GranularityEnum type : GranularityEnum.values()) {
            if(type.value() == value) {
                return type;
            }
        }
        return null;
    }
}

2、创建Strategy接口:

public interface Strategy {
    public int TimeDiffer(Date startTime , Date endTime );
}

3、创建“天、周、月”这三个类并对Strategy接口的实现:

/**
* 天
*/
public class DayStrategy implements Strategy {
    @Override
    public int TimeDiffer(Date startTime, Date endTime) {
        TimeC timeC=new TimeC(startTime,endTime);
        return  timeC.TimeDay();
    }
}
/**
* 周
*/
public class WeekStrategy implements Strategy {
    @Override
    public int TimeDiffer(Date startTime, Date endTime) {
        TimeC timeC=new TimeC(startTime,endTime);
        return  timeC.TimeWeek();
    }
}
/**
* 月
*/
public class MonthStrategy implements Strategy {
    @Override
    public int TimeDiffer(Date startTime, Date endTime) {
        TimeC timeC=new TimeC(startTime,endTime);
        return  timeC.TimeMonth();
    }
}

4、创建一个工厂StrategyFactory类:

public class StrategyFactory {

    private static StrategyFactory factory = new StrategyFactory();
    
    public static StrategyFactory getInstance(){
        return factory;
    }

    private StrategyFactory(){
    }
  
    private static Map strategyMap = new HashMap<>();

    static{
        strategyMap.put(GranularityEnum.DAY.value(), new DayStrategy());
        strategyMap.put(GranularityEnum.WEEK.value(), new WeekStrategy());
        strategyMap.put(GranularityEnum.MONTH.value(), new MonthStrategy());

    }
    public Strategy creator(Integer type){
        return (Strategy) strategyMap.get(type);
    }
}

5、创建context类:

public class Context {

    private Strategy strategy;

    public Strategy getStrategy() {
        return strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public int TimeDiffer(Date startTime , Date endTime , Integer type){
        strategy = StrategyFactory.getInstance().creator(type);
        return strategy.TimeDiffer(startTime, endTime);
    }
}

我们可以从strategy = StrategyFactory.getInstance().creator(type);获取需要创建的是哪个对象,在StrategyFactory类的Map中我们已经存入了相应的三个需要判断创建的对象,最后return中调用TimeDiffer方法得到你需要的数据。

6、客户端中使用:

public class Client{
    public static void main(String[] args){
        Integer key =Integer.parseInt(scheduling.getGranularity());
        Context context = new Context();
        int s = context.TimeDiffer(startTime,endTime, key);
    }
}
 
赞 赏