オブジェクト指向、ちゃんと使えてる?

今日8月1日をもって新しいプロジェクトに移ったわけですが、前のプロジェクトでのお話。とは言っても、プロジェクト固有の話ではなく、単にシステム開発の設計上での話です。


完全に技術寄りの話なので、ある程度知識(デザパタらへん)がないと、読んでもちんぷんかんぷんかも…です。



唐突ですが、下のクラス図をごらんください。

f:id:ikikko:20070802012558p:image

Template Methodの一例です。スーパークラスでは、メソッドの順番が以下のように規定されています。

  1. method1
  2. method2
  3. method3
    1. method3_1
    2. method3_2

ここで、method1, method2は抽象メソッドなのでサブクラスで実装してあげなければなりません。method3は具象クラスですが、中で呼ばれているmethod3_2はこれまた抽象クラスなので、サブクラスで要実装となっています。


この状況で、一次リリースを行いました。



さて、今度は二次リリースではまた別のサブクラスが必要になってきました。ですが、困ったことにTemplate Methodの大枠は使えるのですが、今いちシステム要件とマッチしません。method1 ⇒ method2 ⇒ method3の流れは使いまわせるのですが、method3の中身のmethod3_1 ⇒ method3_2という流れが合っていないのです。


さぁ困った。せっかく拡張しやすいようにTemplate Methodを導入してるのに、一から新しく別に組み立てたくありません。かといって、すでに動いているクラス構成を変更するのも気が引けます。


悩んだあげく、考え付いたのが以下の図。

f:id:ikikko:20070802012617p:image

(幸か不幸か)method3をfinal宣言していなかった*1ので、オーバーライドは可能な状態になっています。ということで、苦し紛れですが新たに追加するClassCでは、method3をオーバーライドして今回の要件にマッチするように書き換えました。



ちょっと二次リリースのときは時間がなかったのであまり検証はしていませんが、こういうやり方って有りなのかな?どこか問題ありそう or 今後問題出てきそう?最近デザインパターンを勉強しているというkさんにでも、是非是非聞いてみたいところ。



以下余談。


いわゆる奥義本を読んでからは*2、できるだけTemplate Methodを避けた方がいいのかなと感じました。というのは、Template Methodは最初の実装は楽で分かりやすくていいのですが、継承を使うので修正の際に弊害がいろいろ出てきやすいのですよね。


気をつけないと、すぐにオープン・クロースドの原則やリスコフ置換原則に違反してしまいます。


この辺の具体的な説明は、私のつたない言葉より↑で紹介した本を読む方が数倍早いでしょう。ちょっと、いやかなり重いですが、それだけの価値がある本です。願わくば、OOPに携わる人は全員目を通してもらいたい本。


アジャイルソフトウェア開発の奥義

アジャイルソフトウェア開発の奥義

*1:Template Methodでは普通サブクラスで書き換えるということがないので、final宣言をしておくのが一般的

*2:まだ読んでる最中ですが…