テンプレートメソッドパターン

今日の役に立たない一言 − Today’s Trifle! −でテンプレートメソッドパターンについてのエントリを読んでいて、そういえば最近つかっているなーと。
Flex というか AS3 でですが。


ところで、AS3 では abstract メソッドというものが無いです*1。なので、abstract メソッドを用意して、メソッドの実装を子クラスに強制させるということが出来ません。

でも、実装もれとか、子クラスでオーバーライドさせることが前提の空のメソッドを用意するとかはイヤです。そこで、私は次のような方法をとっています。

  • 子クラスに実装させたいメソッドを規定したインタフェースを用意します
  • 基底クラスでは、上記のインタフェース型の仮引数をもつコンストラクタを定義します
  • 基底クラスでは、必要な箇所でコンストラクタ引数で受け取っておいたオブジェクトのメソッドを呼び出します
  • 基底クラスを継承し、上記のインタフェースを実装したコンクリートクラスを作成
  • コンクリートクラスのコンストラクタでは、super(this) を呼び出し、自身のインスタンスを基底クラスに渡す

以下、ソースコード例です。

public interface IFoo {
  function processHeader():void;
  function processBody():void;
  function processFooter();void;
}

public class BaseFoo {
  private var _self:IFoo;
  public function BaseFoo(self:IFoo) {
    _self = self;
  }

  public function process():void {
    _self.processHeader();
    なんたら
    _self.processBody();
    かんたら
    _self.processFooter();
  }
}

public class ConcreteFoo extends BaseFoo implements IFoo {
  public function ConcreteFoo() {
    super (this);
  }
  public function processHeader():void {
    ほげ
  }
  public function processBody():void {
    ふぐ
  }
  public function processFooter():void {
    はげ
  }
}

この例だと別に子クラスである必要は無いですね(汗

実際に使用しているケースでは以下のような理由もあって、子クラスにしています。

  • 子クラスのメソッドでは、基底クラスのプロパティを利用している
  • 子クラスの型が必要(型による判断をしている箇所があるため)
  • 便利メソッドを基底クラスに用意して、打鍵数を減らしたい(w

*1:abstract クラスも無いです