2016-12-15 6 views
0

Ich habe unterhalb von Enum, von dem ich entsprechende execute Methode Basis aufrufen, welche Art von enum (eventType) übergeben wird.Wie Code in mehreren Aufzählungsnamen wiederverwenden?

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 
    } 
} 

Zum Beispiel: Wenn ich "EventA" bekommen, dann execute Methode Ich rufe es ist. Ähnlich, wenn ich "EventB" bekomme, dann rufe ich es ist execute Methode und so weiter.

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); 

Im Allgemeinen werde ich mehr Ereignistypen hat (etwa 10-12) in der gleichen Enum-Klasse und meist werden sie gleichen Vorgang wie Eventa, EventB und EventC tun.

Frage:

Nun, wie Sie sehen können, Code in execute Methode von EventA und EventC sind identisch ähnlich, aber der einzige Unterschied ist, was ich als "key" (event name) in der zurück unveränderlichen Karte setzen. Gibt es eine Möglichkeit, diesen duplizierten Code zu entfernen, aber immer noch die gleiche Funktionalität in der Enumeration zu erreichen.

Zum Beispiel etwas auf diesem Boden. Indem Sie mehrere Enums nebeneinander schreiben, die durch ein Komma getrennt sind (wenn die Funktionalität der Ausführungsmethode gleich ist). Ich weiß, dass das nicht funktioniert, weil ich eine abstrakte Methode habe, die ich überall implementieren muss, aber ist es immer noch möglich, einige Änderungen oder andere bessere Methoden zu machen?

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 
} 

Ich kenne einen Weg, um ein Verfahren mit allen gängigen Dinge zu machen und jene Methode aufrufen, durch geeignete Event-Typ Enum Name übergeben. Gibt es einen anderen Weg, als Enum-Features oder andere Änderungen zu verwenden?

Wenn es irgendeinen anderen besseren Weg oder irgendein anderes Entwurfsmuster gibt, um dies zu tun, bin ich offen für Vorschläge, die mir helfen können, doppelten Code zu entfernen.

Idee ist - basierend auf welche Art von Ereignis übergeben wird, möchte ich seine Ausführungsmethode aufrufen und Doppelarbeit zu vermeiden, wenn möglich.

+0

Machen Sie nicht "execute" abstrakt, und dann den Code, der sich in der Überschreibung ändert und rufen Sie es aus "Ausführen". – 4castle

+0

Bedeutung? Nicht ganz folgen. Wenn ich es nicht abstrakt mache, kann ich für jede Enumeration keine individuelle Ausführungsmethode aufrufen. – john

+0

Ich sage, den Teil zu extrahieren, der in seine eigene abstrakte Methode übergeht, und 'execute' zu ​​konkretisieren. – 4castle

Antwort

1

Es gibt zwei einfache Mechanismen (die natürlich kombiniert werden können).

Die erste besteht darin, die execute() in der Basisklasse in Atomen, an spezifischem Code in jeder Unterklasse (dh die Schablonenmethode) definiert Delegieren:

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

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

    protected abstract void specificCode(); 
} 

Die zweite besteht außer Kraft gesetzt, die execute() in mit in Jede Unterklasse delegiert jedoch zu einer gemeinsamen Methode, die in der Basisklasse definiert ist:

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

    public abstract void execute(); 

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

Ich sehe, ich habe jetzt eine Idee.Der zweite Ansatz, den Sie erwähnt haben, ist genau der, an den ich früher gedacht habe, aber dann wurde mir klar, dass es vielleicht einen anderen Ansatz dafür gibt. Also, welcher Ansatz sollte generell in meinem Fall verwendet werden? – john

0

So etwas Ähnliches?

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 
    } 
} 
Verwandte Themen