枚举之间的共享方法

时间:2011-11-21 10:04:10

标签: java groovy enums

我想在两个新枚举中重构一个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')

    ...
}

4 个答案:

答案 0 :(得分: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控制台中运行上面的代码,以证明它可以像宣传的那样工作

答案 1 :(得分:2)

枚举不能扩展任何其他类,因为所有枚举都会自动扩展名为Enum的类。因此,您唯一的选择是将方法实现委托给单独的实用程序。如果实现不是微不足道的(多于一行),这可能是相关的。否则代表团不会给你带来很大的好处。

其他可能性是手动扩展Enum,但我已准备好编写详细代码,如valueOf()values()等,所以我不确定你真的需要这个。

修改

查看我关于Hierarchical Enums的文章。它也可能对你有帮助。

答案 2 :(得分: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')

答案 3 :(得分:0)

Enum类型无法执行此操作,但您可以使用Groovy Mixin或带有接口的工厂:

  1. 在枚举中,只需定义常量即可。所有枚举必须实现公共标记接口。
  2. 创建一个接受标记接口并包含getter的工厂。
  3. 工厂方法允许您将配置(如模板,电子邮件地址)移动到工厂在启动时读取的配置文件中。

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