【问题标题】:How to call enum method basis on what type it is passed?如何根据传递的类型调用枚举方法?
【发布时间】:2016-12-12 02:20:29
【问题描述】:

我有下面的枚举,如下所示,我需要根据它是什么类型的事件来调用它的适当方法。

public enum EventType {

  EventA {
    // cannot call this method
    public Map<String, Map<String, String>> execute(String eventMapHolder) {
      final Map<String, String> holder = parseStringToMap(eventMapHolder);
      if (holder.isEmpty() || Strings.isNullOrEmpty(holder.get("m_itemId"))) {
        return ImmutableMap.of();
      }
      String itemId = holder.get("m_itemId");
      Map<String, String> clientInfoHolder = getClientInfo(itemId);
      holder.putAll(clientInfoHolder);
      return ImmutableMap.<String, Map<String, String>>builder().put(EventA.name(), holder)
          .build();
    }
  },
  EventB {
    // cannot call this method
    public Map<String, Map<String, String>> execute(String eventMapHolder) {
      final Map<String, String> holder = parseStringToMap(eventMapHolder);
      if (holder.isEmpty() || Strings.isNullOrEmpty(holder.get("m_itemId"))) {
        return ImmutableMap.of();
      }
      return ImmutableMap.<String, Map<String, String>>builder().put(EventB.name(), holder)
          .build();
    }
  };

  public Map<String, String> parseStringToMap(String eventMapHolder) {
    // parse eventMapHolder String to Map
  }

  public Map<String, String> getClientInfo(final String clientId) {
    Map<String, String> clientInfoMap = Maps.newHashMap();
    // code to populate this map
    return clientInfoMap;
  }

  public Map<String, String> getDeviceInfo(final String itemId) {
    Map<String, String> deviceInfoMap = Maps.newHashMap();
    // code to populate this map
    return deviceInfoMap;
  }
}

问题:

例如:如果我得到"EventA",那么我想调用它的execute 方法。同样,如果我得到"EventB",那么我想将其称为execute 方法,依此类推。目前由于无法在同一个枚举中找到 execute 方法而无法正常工作。

String eventType = String.valueOf(payload.get("eventType"));
String eventMapHolder = String.valueOf(payload.get("eventMapHolder"));
// this below line gives compilation error as it is not able to find execute method.
Map<String, Map<String, String>> processedMap = EventType.valueOf(eventType).execute(eventMapHolder);

我需要根据传递的事件类型执行某些操作。

  • 如果"EventA" 被传递,那么首先我将eventMapHolder 字符串转换为Map(我们称之为持有人),然后我从持有人映射中提取itemId,然后我将itemId 传递给getClientInfo 方法它又返回一个 Map(我们称之为 clientInfoHolder)。然后我将 clientInfoHolder 映射中的所有内容放入 holder 映射中,最后返回另一个基于 holder 的映射及其密钥。
  • 如果"EventB" 被传递,那么首先我将eventMapHolder 字符串转换为Map(我们称之为持有者),然后我在holder 映射及其键上创建一个新的不可变映射基础并返回该映射。

一般来说,我会在同一个枚举类中拥有更多的事件类型,并且大多数情况下它们会执行与 EventA 和 EventB 相同的操作。

使这项工作正常进行的正确方法是什么?如何调用该特定枚举类型的方法?

如果有任何其他更好的方法或任何其他设计模式可以做到这一点,那么我也愿意提供建议。

【问题讨论】:

    标签: java oop design-patterns enums


    【解决方案1】:

    您可以在enum 上定义抽象方法,只要您在每个枚举实例中覆盖该方法即可。这是一个简单的例子:

    public enum EnumWithMethod {
    
      VALUE_A {
        @Override
        public String enumMethod(String s) {
          return s + "-A";
        }
      },
      VALUE_B{
        @Override
        public String enumMethod(String s) {
          return s + "-B";
        }
      };
    
      public abstract String enumMethod(String s);
    
    }
    

    因此,给定一个任意 Enum 实例,您可以调用 enumMethod:

    EnumWithMethod e = EnumWithMethod.VALUE_A;
    String str = e.enumMethod("asdf"); //asdf-A
    

    对于您的示例,这就像添加一样简单

    public abstract Map<String, Map<String, String>> execute(String eventMapHolder);
    

    到您的EventType 枚举。

    【讨论】:

    • 现在明白了。。感谢您的帮助。您认为这是解决此类问题的正确模式吗?在这里使用枚举并在同一个枚举类中编写一堆代码?一般来说,我将在那个枚举中有大约 15 个 EventType,所以我的班级会很大。您是否看到任何其他模式可以做同样的事情并且可能非常适合此类问题?
    • 这种方法最大的好处是它迫使您在每个实例中都实现该方法。主要替代方案是一个巨大的switch 块,无论是在这里还是在辅助实用程序类中,但是当我看到这些时我会感到紧张,因为当您添加新枚举时很容易(尤其是随着项目的增长)忘记更新它价值。如果您只使用一种方法,我认为这很好。如果您开始实现大量它们,也许将这些方法拉到不同的类中?
    猜你喜欢
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    相关资源
    最近更新 更多