如何在多个枚举名称中重用代码?

时间:2016-12-15 23:51:33

标签: java oop design-patterns enums

我在Enum下面从中调用适当的execute方法基于什么类型的枚举(eventType)传递。

public enum EventType {

  EventA {
    @Override
    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 {
    @Override
    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();
    }
  },
  EventC {
    @Override
    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(EventC.name(), holder)
          .build();
    }
  };

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

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

  public Map<String, String> getClientInfo(final String clientId) {
    // code to populate the map and return it
  }
}

例如:如果我得到"EventA",那么我称之为execute方法。同样,如果我得到"EventB",那么我就会调用它execute方法,等等。

String eventType = String.valueOf(payload.get("eventType"));
String eventMapHolder = String.valueOf(payload.get("eventMapHolder"));
Map<String, Map<String, String>> processedMap = EventType.valueOf(eventType).execute(eventMapHolder);

一般来说,我会在同一个枚举类中有更多的事件类型(大约10-12个),并且大多数它们将执行与EventA,EventB和EventC相同的操作。

问题:

现在您可以看到,executeEventA的{​​{1}}方法中的代码完全相同,但唯一的区别是我在返回的不可变项中放置EventC的内容地图。有没有办法删除重复的代码,但仍然在枚举中实现相同的功能。

例如,在此基础上的东西。通过用逗号分隔并排编写多个枚举(如果执行方法功能相同)。我知道这不起作用,因为我有一个抽象的方法,我需要在任何地方实现它,但是仍然可以通过做出一些改变或任何其他更好的方式吗?

"key" (event name)

我知道一种方法是使用所有常见的东西创建一个方法,并通过传递适当的事件类型枚举名称来调用这些方法。除了使用枚举功能或任何其他更改之外还有其他方法吗?

如果还有其他更好的方式或任何其他设计模式,那么我愿意接受建议,这可以帮助我删除重复的代码。

理念是 - 基于什么类型的事件传递,我想调用它的execute方法并尽可能避免重复。

2 个答案:

答案 0 :(得分:1)

有两种简单的机制(当然可以合并)。

第一个包括在基类中使用execute(),委托给每个子类中定义的特定代码(即模板方法模式):

enum Foo {
    A {
        @Override
        protected void specificCode() {
            //...
        }
    },
    B {
        @Override
        public void specificCode() {
            //...
        }
    };

    public void execute() {
        // ... common code
        specificCode();
        // ... common code
    }

    protected abstract void specificCode();
}

第二个包括在每个子类中重写execute()但是委托给基类中定义的公共方法:

enum Foo {
    A {
        @Override
        public void execute() {
            //...
            commonCode();
            // ...
        }
    },
    B {
        @Override
        public void execute() {
            //...
            commonCode();
            // ...
        }
    };

    public abstract void execute();

    protected void commonCode() {
        // ...
    }
}

答案 1 :(得分:0)

这样的东西?

package enumCodeReuse;

import java.util.Map;

import com.google.common.collect.ImmutableMap;

public enum EventType2 {

    EventA 
    , EventB 
    , EventC 
    ;

    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(this.name(), holder)
                .build();
    };

    public Map<String, String> parseStringToMap(String eventMapHolder) {
        // parse eventMapHolder String to Map
        return null; // FIXME
    }

    public Map<String, String> getClientInfo(final String clientId) {
        // code to populate the map and return it
        return null; // FIXME
    }
}