I want to refactor an emun in two new enums, but I don't like to copy/paste the enum methods in all new enums.
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) {
...
}
...
}
It's possible to implements only one time the methods and use in several enums?
enum EmailTypeAdministration {
REMINDER_ADMIN('reminderForAdmin')
REMINDER_PRODUCTION('reminderForProduction')
...
}
enum EmailTypeClients {
REMINDER_MANAGEMENT('reminderForManagement')
REMINDER_CUSTOMER('reminderForCustomer')
...
}
The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.
An enum can, just like a class , have attributes and methods. The only difference is that enum constants are public , static and final (unchangeable - cannot be overridden).
Below code uses enums with defined methods: We should define methods as abstract methods and then we have to implement defferent flavours/logic based on each enum members. Because of declaring abstract method at the enum level; all of the enum members require to implement the method.
Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.
As my old friend Clippy would say, "it looks like you're using Groovy". If so, you can use a mixin to add the common methods to both enums.
// 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')
You can run the code above in the Groovy console to prove it works as advertised
Enums cannot extend any other class since all enums automatically extend class named Enum
. So, your only option is to delegate the methods implementation to separate utility. This may be relevant if the implementation is not trivial (more than one line). Otherwise delegation does not give you serious benefits.
Other possibility is to extend Enum manually but I be ready to write verbose code like valueOf()
, values()
etc., so I am not sure you really need this.
EDIT:
Take a look on my article about Hierarchical Enums. It can probably help you too.
Finally the Mixin solution don't works because @Mixin
annotation only works with classes instead of enums.
I use a similar approach with delegate. Delegate transformation works fine! This code can be improve to use EnumUtils with factory or singleton pattern.
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With