倭マン's BLOG

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

アノテーションでデザインパターンの役割をマークする (6):「Iterator パターンの役割マーク」改善の試み 其ノ壱

今回は、前回行った「『Java 言語で学ぶデザインパターン入門(結城浩)を参考にしてみる』」の続き。 少々、改善を試みます。

改善点


今回改善を試みる箇所は、「Iterator と ConcreteIterator、Aggregate と ConcreteAggregate の間でメソッドに付加するアノテーションがカブっている」点です。

この「カブり」は型定義とその実装という観点から当然のことですが、アノテーションの定義が助長になるので簡略化しましょう。 アノテーション型でも継承ができるなら

public @interface ConcreteIterator extends Iterator{}

みたいな解決方法も可能ですが(それがいいかどうかは別にして)、Java SE 6 ではそうなっていないので別の方法をとります。

解決方法は、単純に ConcreteXxxx アノテーションに定義されている子アノテーションを除去します。 これらは実装すべきインターフェースに定義されているメソッドなので、特にマーク付けする必要はないかなと。 強いて言うなら、@Override アノテーション (@java.lang.Override) を付加すればいいかなと思います。

これらのメソッドも一応デザインパターンの一部ということで、全く何もマークしないことがどうかなとも思うので、これらのアノテーションが「継承される」ように @Inherited アノテーション (@java.lang.annotation.Inherited) を付け加えておくのがいいのではないでしょうか*1

アノテーションを定義する Java コード


上記の改善点を踏まえたアノテーション定義は以下のようになります。

package org.waman.tools.design.gof.IteratorPattern;

import java.lang.annotation.*;

public final class IteratorPattern {
    
    private IteratorPattern(){}
        
    /** 集約子 */
    @Target(ElementType.TYPE)
    public static @interface Aggregate{
        
        /** 反復子を生成するメソッド */
        @Inherited
        @Target(ElementType.METHOD)
        public static @interface CreateIterator{}
    }

    /** 具象集約子 */
    @Target(ElementType.TYPE)
    public static @interface ConcreteAggregate {}

    /** 反復子 */
    @Target(ElementType.TYPE)
    public static @interface Iterator {

        /** 次の要素があるかどうかの問い合わせを行うメソッド */
        @Inherited
        @Target(ElementType.METHOD)
        public static @interface HasNext {}

        /** 次の要素を取得するメソッド */
        @Inherited
        @Target(ElementType.METHOD)
        public static @interface Next {}
    }

    /** 具象反復子 */
    @Target(ElementType.TYPE)
    public static @interface ConcreteIterator {}
}

サンプルコード in 『Java 言語で学ぶデザインパターン入門』


では、具体的なサンプルについて、上記のアノテーション定義を付加してみましょう。 サンプルは前回と同じように、『Java 言語で学ぶデザインパターン入門』の Iterator の章に載っているものです(メソッドを Generic に変更してますが)。

Book クラス, Iterator インターフェース, Aggregate インターフェース

これらの型は前回と同じです。

BookShelf クラス

Aggregate の具象クラス。 Aggregate インターフェースに定義されているメソッドには @Override アノテーション (@java.lang.Override) を付加していますが、必須と言うわけではありません。

import org.waman.tools.design.gof.IteratorPattern;
import org.waman.tools.design.gof.IteratorPattern.ConcreteAggregate.CreateIterator;

@IteratorPattern.ConcreteAggregate
public class BookShelf implements Aggregate<Book>{
    ...
    @Override public Iterator<E> iterator(){...}
}

@Override アノテーションに加えて、@IteratorPattern.Aggregate.CreateIterator アノテーションを付加してもいいかも知れません。

BookShelfIterator クラス

Iterator の具象クラスです。 Iterator インターフェースに定義されているメソッドに関しては @Override アノテーション (@java.lang.Override) を付加していますが、必須と言うわけではありません。

import org.waman.tools.design.gof.IteratorPattern;

@IteratorPattern.ConcreteIterator
public class BookShelfIterator implements Iterator<Book> {
    @Override public boolean hasNext(){...}
    @Override public E next(){...}
}

@Override アノテーションに加えて、@IteratorPattern.Iterator.HasNext, @IteratorPattern.Iterator.Next アノテーションを付加してもいいかも知れません。
まぁ、総じてあんまり変わってないかな?

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門


オブジェクト指向における再利用のためのデザインパターン

オブジェクト指向における再利用のためのデザインパターン

  • 作者: エリックガンマ,ラルフジョンソン,リチャードヘルム,ジョンブリシディース,Erich Gamma,Ralph Johnson,Richard Helm,John Vlissides,本位田真一,吉田和樹
  • 出版社/メーカー: ソフトバンククリエイティブ
  • 発売日: 1999/10
  • メディア: 単行本
  • 購入: 21人 クリック: 711回
  • この商品を含むブログ (201件) を見る

*1:メソッドに付加するアノテーションに @Inherited を付加するなら、型に付加するアノテーション @Iterator, @Aggregate にも @Inherited を付加した方がいい気もしますが・・・ 「@Inherited アノテーション」って、いまいち使いどころが分からないというか、どのアノテーションにも必要な気もするし、どのアノテーションにも不必要な気もするアノテーション