2011-11-21 8 views
7

Chcę refaktoryzować emun w dwóch nowych wyliczeniach, ale nie lubię kopiować/wklejać metod wyliczania we wszystkich nowych wyliczeniach.Metody współdzielone między enumami

enum EmailType { 
    REMINDER_ADMIN('reminderForAdmin') 
    REMINDER_PRODUCTION('reminderForProduction') 
    REMINDER_MANAGEMENT('reminderForManagement') 
    REMINDER_CUSTOMER('reminderForCustomer') 

    private final propertiesIdentifier 

    String getTemplate(type) { 
     ... 
    } 

    String getFrom(type) { 
     ... 
    } 

    String getTo(type) { 
     ... 
    } 

    String getBcc(type) { 
     ... 
    } 

    ... 
} 

To możliwe realizuje tylko jeden raz i używać metod w kilku teksty stałe?

enum EmailTypeAdministration { 
    REMINDER_ADMIN('reminderForAdmin') 
    REMINDER_PRODUCTION('reminderForProduction') 

    ... 
} 

enum EmailTypeClients { 
    REMINDER_MANAGEMENT('reminderForManagement') 
    REMINDER_CUSTOMER('reminderForCustomer') 

    ... 
} 
+1

Uważa, że ​​nie jest to możliwe, ale twoje wyliczenia mogą zaimplementować ten sam interfejs, dzięki czemu można uzyskać dostęp do metod za pośrednictwem interfejsu. – Stephan

Odpowiedz

2

Wreszcie Mixin solution nie działa, ponieważ adnotacja działa tylko z klasami zamiast wyliczeń.

Używam podobnego podejścia z delegatem. Delegate transformation działa dobrze! Kod ten można ulepszyć, aby używać EnumUtils z wzorcem fabrycznym lub singleton.

class EnumUtils { 
    String getTemplate(type) { 
     "template" + type  
    } 

    String getFrom(type) {   
    } 

    String getTo(type) {   
    } 

    String getBcc(type) {   
    } 
} 

enum EmailTypeAdministration { 
    REMINDER_ADMIN('reminderForAdmin'), 
    REMINDER_PRODUCTION('reminderForProduction') 

    @Delegate EnumUtils enumUtils = new EnumUtils() 
    EmailTypeAdministration(str) {} 
} 

enum EmailTypeClients { 
    REMINDER_MANAGEMENT('reminderForManagement'), 
    REMINDER_CUSTOMER('reminderForCustomer') 

    @Delegate EnumUtils enumUtils = new EnumUtils() 
    EmailTypeClients(str) {} 
} 

EmailTypeAdministration emailTypeAdmin = EmailTypeAdministration.REMINDER_ADMIN 
assert 'templateParam' == emailTypeAdmin.getTemplate('Param') 
+0

Rozwiązanie mixin działa –

2

wyliczenia nie można rozszerzyć do innej grupy, ponieważ wszystkie teksty stałe automatycznie rozszerzyć klasę o nazwie Enum. Tak więc jedyną opcją jest delegowanie implementacji metod do oddzielnego narzędzia. Może to być istotne, jeśli implementacja nie jest trywialna (więcej niż jeden wiersz). W przeciwnym razie delegacja nie przyniesie ci poważnych korzyści.

Inną możliwością jest rozszerzenie Enum ręcznie, ale jestem gotowy do napisania pełnego kodu, takiego jak valueOf(), values() itd., Więc nie jestem pewien, czy naprawdę tego potrzebujesz.

EDIT:

Spójrz na mojego artykułu o Hierarchical Enums. Prawdopodobnie może ci pomóc.

+0

Dzięki, używam Groovy i mogę zaimplementować w jednym wierszu z [Transformacja Delegata] (http://groovy.codehaus.org/Delegate+transformation) –

9

Mój stary przyjaciel Clippy powiedziałby "wygląda na to, że używasz Groovy". Jeśli tak, możesz użyć polecenia mixin, aby dodać typowe metody do obu wyliczeń.

// This class holds the methods that will be mixed-in to the enums 
class EnumUtils { 
    String getTemplate(type) { 
     "template" + type  
    } 

    String getFrom(type) {   
    } 

    String getTo(type) {   
    } 

    String getBcc(type) {   
    } 
} 

// This annotation adds the common methods to the enum 
@Mixin(EnumUtils) 
enum EmailTypeAdministration { 
    REMINDER_ADMIN('reminderForAdmin'), 
    REMINDER_PRODUCTION('reminderForProduction') 

    EmailTypeAdministration(str) {} 
} 

// This annotation adds the common methods to the enum 
@Mixin(EnumUtils) 
enum EmailTypeClients { 
    REMINDER_MANAGEMENT('reminderForManagement'), 
    REMINDER_CUSTOMER('reminderForCustomer') 

    EmailTypeClients(str) {} 
} 

// Quick test to prove the methods exist and return the expected values 
EmailTypeAdministration emailTypeAdmin = EmailTypeAdministration.REMINDER_ADMIN 
assert 'templateParam' == emailTypeAdmin.getTemplate('Param') 

można uruchomić powyższy kod w konsoli Groovy, aby udowodnić, że działa jak reklamowane

+0

Nie mogę tego uruchomić ... Jaka jest wersja pracujesz pod? –

+0

@tim_yates działa dla mnie w konsoli groovy 1.8.2 –

+0

Interesujące, myślę, że można również użyć @Delegate –

0

Typ Enum nie mogę tego zrobić, ale można użyć Groovy Mixin s lub fabrykę z interfejsem:

  1. W tabelach po prostu zdefiniuj stałe. Wszystkie wyliczenia muszą implementować wspólny interfejs znaczników.
  2. Utwórz fabrykę, która akceptuje interfejs znacznika i zawiera moduły pobierające.

Podejście fabryczne pozwala przenieść konfigurację (np. Szablony, adresy e-mail) do pliku konfiguracyjnego, który fabrycznie odczytuje przy uruchomieniu.

Lekcja: Nie umieszczaj konfiguracji w wyliczeniach. Wyliczenia są stałymi. Zmiany w konfiguracji.

Powiązane problemy