2011-11-21 123 views
7

我想在兩個新的枚舉中重構一個emun,但我不喜歡在所有新枚舉中複製/粘貼枚舉方法。枚舉之間的共享方法

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) { 
     ... 
    } 

    ... 
} 

這是可能的實現只有一次的方法,並在幾個枚舉使用?

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

    ... 
} 

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

    ... 
} 
+1

它認爲這是不可能的,但是你的枚舉可以實現相同的接口,所以你可以通過接口訪問這些方法。 – Stephan

回答

2

最後,Mixin solution不起作用,因爲@Mixin註釋僅適用於類而不是枚舉。

我對委託使用了類似的方法。 Delegate transformation工作正常!可以改進此代碼以使用工廠或單例模式使用EnumUtils。

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

mixin解決方案確實有效 –

2

枚舉不能擴展任何其他類,因爲所有枚舉自動擴展名爲Enum類。因此,唯一的選擇是將方法實現委託給單獨的實用程序。如果實現不是微不足道的(多於一行),這可能是相關的。否則,授權不會給您帶來嚴重的好處。

另一種可能是手動擴展Enum,但我可以編寫冗長的代碼一樣valueOf()values()等等,所以我不知道你真的需要這一點。

編輯:

拿上我的文章有關Hierarchical Enums看看。它也可以幫助你。

+0

謝謝,我正在使用Groovy,並且可以在[代理轉換](http://groovy.codehaus.org/Delegate+transformation) –

9

正如我的老朋友Clippy會說,「看起來您正在使用Groovy」。如果是這樣,你可以使用一個mixin將常用方法添加到兩個枚舉中。

// 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') 

可以在Groovy的控制檯中運行上面的代碼,以證明它像宣傳的那樣

+0

中實現一行。我無法運行它...它是什麼版本在下工作? –

+0

@tim_yates適用於Groovy控制檯1.8。2 –

+0

有趣的是,我認爲也可以使用@Delegate –

0

Enum類型不能這樣做,但你可以使用Groovy Mixin S或A工廠的接口:

  1. 在枚舉中,只需定義常量。所有枚舉必須實現一個通用標記接口。
  2. 創建一個接受標記接口幷包含吸氣劑的工廠。

工廠方法允許您將配置(如模板,電子郵件地址)移動到工廠在啓動時讀取的配置文件中。

課程:不要將配置放入枚舉中。枚舉是常量。配置更改。