2011-11-21 12 views
7

2つの新しい列挙体でemunをリファクタリングする必要がありますが、すべての新しい列挙型でenumメソッドをコピー/貼り付けするのは嫌いです。列挙型の間の共有メソッド

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という名前のクラスを拡張するので

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

    ... 
} 

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

    ... 
} 
+1

これは不可能だと思いますが、enumは同じインターフェイスを実装できるため、インターフェイス経由でメソッドにアクセスできます。 – Stephan

答えて

2

最後に@Mixin注釈は列挙型ではなくクラスでのみ機能するため、Mixin solutionは機能しません。

私はデリゲートで同様のアプローチを使用します。 Delegate transformationはうまく動作します!このコードは、FactoryまたはSingletonパターンで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

ミックスインのソリューションが機能する –

2

列挙型は、他のクラスを拡張することはできません。だから、あなたの唯一の選択肢は、メソッド実装を別のユーティリティに委譲することです。実装が些細なものではない場合(複数の行)、これは関連している可能性があります。そうでなければ、委任はあなたに大きな利益を与えません。

手動でEnumを拡張することも可能ですが、valueOf(),values()などのような冗長コードを書く準備ができているので、本当に必要なのか分かりません。

EDIT:

Hierarchical Enumsについての私の記事で見てください。それはおそらくあなたを助けることもできます。

+0

ありがとう、私はGroovyを使用しており、[Delegate transformation](http://groovy.codehaus.org/Delegate+transformation)で1行に実装することができます –

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

あなたはEnumタイプはそれを行うことはできませんが、あなたはGroovyのMixin Sまたはインタフェースを備えた工場を使用することができます

+0

実行することができません...どのバージョンですか下で働く? –

+0

@tim_yatesはgroovy console 1.8で動作します。2 –

+0

興味深いことに、@Delegateを使用することもできます –

0

宣伝通りに動作するか検証するためにGroovyのコンソールで上記のコードを実行することができます。

  1. 列挙型では、定数を定義するだけです。すべてのenumは、共通マーカーインタフェースを実装する必要があります。
  2. マーカーインターフェイスを受け入れ、ゲッターを含むファクトリを作成します。

工場出荷時のアプローチでは、テンプレート(電子メールアドレスなど)をファクトリが起動時に読み込む設定ファイルに移動することができます。

レッスン:構成を列挙型に入れないでください。列挙型は定数です。構成の変更。

関連する問題