APTでテンプレートメソッドパターンを生成する その1

アノテーションプロセシングツール(APT)のまとめとして、テンプレートメソッドパターンの具象クラスを自動生成するアノテーションプロセッサについて書いておこうと思う。

  • テンプレートメソッドパターンとは?

いわずとしれたオブジェクト指向実装設計における、継承関係を利用した抽象->具象実装を利用した汎用的なデザインパターン。※オブジェクト指向設計を学ぶにあたり最も理解しやすいパターンの一つなので、GoF本で紹介される以前から最もメジャーに使用されてきたパターンだ。
Template Method パターン - Wikipedia

  • 抽象クラスを用意する

別に具象クラスでも良いのだが、テンプレートとなるルートクラスはインスタンス化しない抽象クラスで用意することが多い。

今回は対象プラットホームをAndroidとし、サーバからHTTPレスポンスとして取得したストリームからXMLをパースする、XlmPullParserのパース結果を任意の派生クラスのPOJOとして生成するので、テンプレートメソッドはXlmPullParserパーサを引数に取る、parseメソッドということにしよう。

    • 抽象クラス AbstractXmlDto.java (好みだが、抽象クラスのプレフィクスには"Abstract"を指定する)
import java.io.IOException;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

public abstract class AbstractXmlDto {
    public abstract void parse(XmlPullParser parser) throws XmlPullParserException, IOException ;
}

最低限の実装。本当ならここにエラー処理(特にパース時の)が必要なのだが割愛する。

今回のアノテーションプロセッサはアノテーションを記述するだけのダミーのクラス、又はインタフェースに専用のアノテーションを記述することでテンプレートから派生した具象クラスを生成する。

アノテーションに必要なのは以下の属性とする。

    • Java Beanのアクセサ(getter/setter)生成の有無
    • 生成する具象クラスのクラス名(FQN) (記述しなければ既定の名前が使われる)
    • パース時にJava Objectにマップするためのアノテーションの組(フィールド数分)

 *XML要素名
 *フィールド名(同じ場合はフィールド名は省略する)
 *フィールドの型(デフォルトは文字列型)

@Documented
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface XmlAutoBean {
    boolean getter() default true;
    boolean setter() default true;
    String beandClass() default "";
    Element[] elements() default {};
}
@Documented
@Inherited
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Element {
    String name();
    String fieldName() default "";
    Class type() default java.lang.String.class;
}

続きは年明けかなぁ。


※今、デザインパターンと書くと懐かしさと気恥ずかしさの両方を感じるな。