首页 > 解决方案 > 我应该将多态性用于简单的 switch 语句吗?

问题描述

我是清理代码/重构的新手,我学会了避免像下面这样长的 switch 语句。我发现多态性是一种有用的技术来缩短复杂的 switch 语句。对于这个简单的 switch 语句,多态性是一个好主意吗?

String periodValue;
int numberOfDataPoints;

getNumberOfDataPoints(String selectedGraphType) {
    switch (selectedGraphType) {
      case "1D": 
        {
          periodValue = "300";
          numberOfDataPoints = 289; 
        }
        break;
      case "5D": 
        {
          periodValue = "1800";
          numberOfDataPoints = 241;
        }
        break;
      case "1M": 
        {
          periodValue = "86400";
          numberOfDataPoints = 31;
        }
        break;
      case "1Y": 
        {
          periodValue = "259200";
          numberOfDataPoints = 123;
        }
        break;
  }

}

标签: javaswitch-statementpolymorphismrefactoringcode-cleanup

解决方案


您不需要多态性,您可以只使用一个组合两个值的类和一个 Map 来省略 switch 语句。

public class GraphType {
   // made the fields public final and omitted the getters for simplicity.
   // add getters if needed

   public final int periodValue;
   public final int numberOfDataPoints;

   GraphType(int periodValue, int numberOfDataPoints) {
      this.periodValue = periodValue;
      this.numberOfDataPoints = numberOfDataPoints;
   }

}

然后构建地图

Map<String, GraphType> graphTypeByName = new HashMap<>();

graphTypeByName.put("1D",new GraphType(300, 289));
graphTypeByName.put("5D",new GraphType(1800, 241));
graphTypeByName.put("1M",new GraphType(86400, 31);
graphTypeByName.put("1Y",new GraphType(259200, 123);

并使用地图

public GraphType getNumberOfDataPoints(String selectedGraphType) {
    GraphType graphType = graphTypeByName.get(selectedGraphType);

    if(graphType == null) {
       // handle graphType not registered. Default value or exception ?
    }

    return graphType;
}

这种方法比使用枚举更灵活。默认情况也更容易测试。我认为这GraphType不是枚举。枚举是一组不太可能更改的固定名称,例如 NORH、SOUTH、EAST、WEST 或 HOUR、MINUTES、SECONDS。

如果您想确保 a 只有GraphType您想要的 s 存在并且不能实例化其他 s,请实现这样的注册表:

public class GraphTypeRegistry {

    public class GraphType {
       public final int periodValue;
       public final int numberOfDataPoints;

       private GraphType(int periodValue, int numberOfDataPoints) {
           this.periodValue = periodValue;
           this.numberOfDataPoints = numberOfDataPoints;
       }
   }

   private Map<String, GraphType> graphTypeByName = new HashMap<>();

   public GraphTypeRegistry(){
      graphTypeByName.put("1D",new GraphType(300, 289));
      graphTypeByName.put("5D",new GraphType(1800, 241));
      graphTypeByName.put("1M",new GraphType(86400, 31);
      graphTypeByName.put("1Y",new GraphType(259200, 123);
   }

   public GraphType getGraphType(String graphTypeName) {
      GraphType graphType = graphTypeByName.get(graphTypeName);

      if(graphType == null) {
         // handle graphType not registered. Default value or exception ?
      }

      return graphType;
  }
} 

推荐阅读