2011-11-21 92 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. 创建一个接受标记接口并包含吸气剂的工厂。

工厂方法允许您将配置(如模板,电子邮件地址)移动到工厂在启动时读取的配置文件中。

课程:不要将配置放入枚举中。枚举是常量。配置更改。