デザインパターン[TemplateMethod]

さて、今日は短めに行きます。

TemplateMethodデザインパターンの中でも
初めの方に出てくるパターンですね。

継承とはこういうときにこそ使う意義があると教えてくれます。

機能拡張のための継承ははっきり言って悪です。
機能拡張をするなら、継承ではなく、委譲を使いましょう。

とそれはおいといて、
TemplateMethodパターンの概要ですが、
AppletやServletをかじったことがある人なら
すぐ分かると思います。

まさにあの作り方がTemplateMethodパターンに等しいからです。

TemplateMethodパターンとは、
共通箇所をくくりだし、クラスを定義し、
拡張箇所をメソッドとしてくくりだし、その部分のみを継承拡張できるようにしておくパターンです。

Appletで考えて見ましょう。


class AppletTest extends Applet {
public void init() {
}

public void paint(Graphics g) {
}
}

簡単なAppletクラスです。
initやpaintは「〜の時に呼び出される」ように作られています。
「〜の時」にしたいことを書くだけで、
「〜の時」の判断や、(VC++等でWindowsプログラミングをやったことがある人なら良く分かると思いますが)窓の生成や登録は勝手にやってくれいているわけです。 どこがやっているかと言うとAppletクラスです。
ただ、そういう処理は決まりきっているので、親クラスが処理をすれば、子クラスが考える必要が無く、考えなくてはならないことに集中できるわけです。

さて、TemplateMethodパターンはこれだけなのですが、
守った方がいい事がいくつかあります。
これは時と場合によって変動しますので、その時々に合わせてください。

?「決まりきった処理」はprivateメソッドとして用意し、final属性をつけておく。
?「拡張機能のメソッド」はprotectedにしておく。
?「拡張機能のメソッドが親のフィールドに直接アクセスはできないようにし、アクセスしたい場合は引数として渡してやる」

とこんなところです。
全て親クラスの処理を壊さないようにするための処置です。
無作法なプログラマによって、前提が壊されてはたまったもんじゃありませんからね。

それと、TemplateMethodパターンには2つのレベルがあります。
通常は片方をTemplateMethodパターンと言うのかもしれませんが・・・

?「拡張機能のメソッド」は全てabstractにしておく
?「拡張機能のメソッド」は空のメソッドにし、クラスのみをabstractにしておく。

私は?のパターンの方が好きですが、拡張しなくてもいい機能がある場合、?を選択した方がスマートになるでしょうね。