使用Enum进行Java方法重构

c12*_*c12 5 java

下面的getCategory方法似乎非常多余,我想知道是否有人有一些关于重构它的建议,以使其更清洁可能使用Enum.基于传入的"val",我需要getCategory从Category类返回正确的Category实例.Category类是生成的JNI代码,所以我不想改变它.有人有主意吗?

要重构的方法:

private Category getCategory(String val) throws Exception{
        Category category;
        if (val.equalsIgnoreCase("producer")) {
            usageCategory = Category.CATEGORY_PRODUCER;
        } else if (val.equalsIgnoreCase("meter")) {
            usageCategory = Category.CATEGORY_METER;
        } else if (val.equalsIgnoreCase("consumer")) {
            usageCategory = Category.CATEGORY_CONSUMER;
        } else {
            throw new Exception("Invalid value: " + val);
        }       
        return usageCategory;
    }
Run Code Online (Sandbox Code Playgroud)

Category.java:生成的JNI(无法更改):

public final class Category {
  public final static Category CATEGORY_PRODUCER = new Category("CATEGORY_PRODUCER", SampleJNI.CATEGORY_PRODUCER_get());
  public final static Category CATEGORY_METER = new Category("CATEGORY_METER", SampleJNI.CATEGORY_METER_get());
  public final static Category CATEGORY_CONSUMER = new Category("CATEGORY_CONSUMER", SampleJNI.CATEGORY_CONSUMER_get());

}
Run Code Online (Sandbox Code Playgroud)

Pau*_*ora 6

你的方法实际上是从预定的映射String到a Category,所以为什么不使用a Map?具体来说,我推荐Guava ImmutableMap,因为这些映射是静态的:

private static final ImmutableMap<String, Category> CATEGORIES_BY_STRING =
        ImmutableMap.of(
            "producer", Category.CATEGORY_PRODUCER,
            "meter", Category. CATEGORY_METER,
            "consumer", Category.CATEGORY_CONSUMER
        );
Run Code Online (Sandbox Code Playgroud)

或者,如果您不想使用第三方库,则采用标准方式:

private static final Map<String, Category> CATEGORIES_BY_STRING;
static {
    Map<String, Category> backingMap = new HashMap<String, Category>();
    backingMap.put("producer", Category.CATEGORY_PRODUCER);
    backingMap.put("meter", Category.CATEGORY_METER);
    backingMap.put("producer", Category.CATEGORY_CONSUMER);
    CATEGORIES_BY_STRING = Collections.unmodifiableMap(backingMap);
}
Run Code Online (Sandbox Code Playgroud)

您仍然可以使用您的方法来检查无效值(并支持大小写Harkness指出的不区分大小写):

private Category getCategory(String val) {
    Category category = CATEGORIES_BY_STRING.get(val.toLowerCase());
    if (category == null) {
        throw new IllegalArgumentException();
    }
    return category;
}
Run Code Online (Sandbox Code Playgroud)

关于使用枚举:

如果您可以完全控制String传入的s getCategory,并且只传递文字值,那么切换到enum相反的方法确实有意义.

编辑:以前,我建议使用一个EnumMap案例,但阿德里安的答案更有意义.


Adr*_*hum 5

如果你说你想基于枚举进行重构,我认为你的意思是你不再想要传递String到getCategory来完成所有这些工作.代码直接使用枚举,而不是使用String.

如果是这种情况,请继续阅读

幸运的是,您的类别是静态变量,因此您可以直接做一些真正的事情

public enum FooCategory {  // give a better name yourself
  PRODUCER(Category.CATEGORY_PRODUCER),
  METER(Category.CATEGORY_METER),
  CONSUMER(Category.CATEGORY_CONSUMER)

  private Category category;
  FooCategory(Category category) {
    this.category=category;
  }
  Category getCategory() {
    return this.category;
  }
}
Run Code Online (Sandbox Code Playgroud)

在您的旧代码中,您正在执行以下操作:

String fooCategory = "producer";
//....
Category category = getCategory(fooCategory);
// work on category
Run Code Online (Sandbox Code Playgroud)

现在你做的更整洁了

FooCategory fooCategory = FooCategory.PRODUCER;
//...
Category category = fooCategory.getCategory();
// work on category
Run Code Online (Sandbox Code Playgroud)