在代码编写的过程中经常会遇到大量使用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);
}
}