倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

アノテーションでデザインパターンの役割をマークする (3):インターフェース・ベース

今回は「インターフェース・ベースの実現」。 この方法は定数インターフェースパターンと同じようなところがあるので、あまり良くないかと。

アノテーションの実装


「インターフェース・ベースの実現」では、デザインパターン名と同じ名前のインターフェース内に、static メンバーとしてそこで使われるアノテーションを定義します。 アノテーションの定義自体は「パッケージ・ベースの実現」と同じです。
ServiceProvider.java

public interface ServiceProvider {
    
    @Documented
    @Target(ElementType.TYPE)
    @interface Service{}
    
    @Documented
    @Target(ElementType.TYPE)
    @interface Provider {}

    @Documented
    @Target(ElementType.METHOD)
    @interface ProviderRegistration {}

    @Documented
    @Target(ElementType.METHOD)
    @interface ServiceAccess {}
}

アノテーションの使用


上記のアノテーションの使用方法は以下のようになります:

// Effective Java 第2版
// 『項目1 コンストラクタの代わりに static ファクトリーメソッドを検討する』より

@ServiceProvider.Service
public interface Service {
    ...  // サービス固有のメソッドをここに
}

@ServiceProvider.Provider
public interface Provider {
    Service newService();
}

public final class Services {
    ...
    @ServiceProvider.ProviderRegistration
    public static void registrerDefaultProvider(Provider p){...}
    
    @ServiceProvider.ProviderRegistration
    public static void registerProvider(String name, Provider p){...}
    
    @ServiceProvider.ServiceAccess
    public static Service newInstance(){...}
    
    @ServiceProvider.ServiceAccess
    public static Service newInstance(String name){...}
}

幾つか注意を:

  • static インポートを用いれば、(名前が衝突しない限り)@ServiceProvider.Service を @Service のように書けます。 ただし、どのデザインパターンの役割かが分かりやすいので、static インポートをせずに使うのもアリかと。
  • メソッドにアノテーションを付加する場合には、デザインパターンとなるインターフェースを実装するという手もあります。 ただ、定数インターフェースパターンと同じ理由でしない方がいいでしょうけど。
public final class Services implements ServiceProvider{
    ...
    @ServiceAccess    //  @ServiceProvider.ServiceAccess としなくてよい
    public static Service newInstance(){...}
}

Effective Java 第2版 (The Java Series)

Effective Java 第2版 (The Java Series)


川口耕介氏の新連載『やっぱりJavaがスキ!』がスタート↓
WEB+DB PRESS Vol.50

WEB+DB PRESS Vol.50