2016-12-15 4 views
0

私は適切な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と同様の操作を行います。

質問:あなたが見ることができるよう

は今、EventAEventCexecuteメソッドのコードは、同一似ていますが、唯一の違いは、私が戻った不変のマップに"key" (event name)として入れたものです。その重複したコードを削除する方法はありますか?列挙型でも同じ機能を実現します。

たとえば、この地面には何かがあります。カンマで区切られた複数の列挙型を並べて書くことによって(executeメソッドの機能性が同じ場合)私はどこにでも実装する必要がある抽象メソッドを持っているので、これはうまくいかないと知っていますが、いくつかの変更や他の方法でも可能ですか?

public enum EventType { 

    EventA, 
    EventC { 
    @Override 
    public Map<String, Map<String, String>> execute(String eventMapHolder) { 
     // same code which is there in execute method for EventA and EventC 
    } 
    }, 
    EventB { 
    @Override 
    public Map<String, Map<String, String>> execute(String eventMapHolder) { 
     // same code which is there in execute method of EventB 
    } 
    }; 

    // other methods which are there already 
} 

一般的なものすべてを使用してメソッドを作成し、適切なイベントタイプのenum nameを渡してこれらのメソッドを呼び出す方法があります。列挙型の機能やその他の変更を使用して、それ以外の方法はありますか?

これ以外の方法や他のデザインパターンがある場合は、私は重複したコードを削除するのに役立つように、welllとして提案しています。

アイデアは、どのタイプのイベントが渡されるかに基づいて、実行メソッドを呼び出して可能な場合は重複を避けたいと考えています。

+0

抽象的な 'execute'をしないで、変更されたコードを上書きして' execute'から呼び出します。 – 4castle

+0

意味?まったくフォローしなかった。抽象化しなければ、各列挙型に対して個別にexecuteメソッドを呼び出すことはできません。 – john

+0

私は、独自の抽象メソッドに変更された部分を抽出し、 'execute'コンクリートを作成すると言っています。 – 4castle

答えて

1

単純なメカニズムが2つあります(もちろん組み合わせることができます)。

最初のものは、それぞれのサブクラス(すなわち、テンプレートメソッドパターン)で定義された特定のコードに委任、ベースクラスで​​を有することからなる:

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

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

    protected abstract void specificCode(); 
} 

第二つでオーバーライド​​を有することからなります各サブクラスは基本クラスで定義された共通のメソッドに委譲します:

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

    public abstract void execute(); 

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

私は今、アイデアを知っている。あなたが言及した第二のアプローチは、私が以前に使ったと思ったアプローチですが、それには別のアプローチがあるかもしれません。ですから、私の場合、どのアプローチを使うべきですか? – john

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 
    } 
} 
関連する問題