実践的オブジェクト指向分析・設計と実装 (続き)

今日は、昨日学んだことをベースに新しい演習に取り組みました。演習のお題は電話の通話管理システムです。

簡単なユースケースを出発点にして、

  • 1. オブジェクトレベルで関連/多重度を考え、
  • 2. ユースケース実現の詳細度を高めていきます


オブジェクトをしっかり意識せずにクラス図を描いていくと、いざ実装に移るときにうまくいきません。今回は見事に (先生の用意していた) 落とし穴にはまってしまいました。 (^^;


下のようなクラス図 (その1) を書くと、オブジェクトレベルではその下のオブジェクト図 (その1) のような構成が考えられます。C クラスの個々のオブジェクト (c1 .. c4 ) に A、B のオブジェクト (a、b) 両方からの参照をもつわけです。ただし、今回考えていたユースケースでは、b から C のオブジェクトを新たに追加するというものがありました。



ここで、実際に追加する実装のイメージを膨らませていくと、追加自体は C を new して b でもっている配列なりリストなりに追加すればよさそうだなと思うわけですが、困るのは a からの参照をどうもたせるかです。B から A には関連をもたせていないので、どうにも手がありません。クラス図 (その1) は、何となく雰囲気は出ているものの、実際にはコードに落ちない代物だったわけです。


ちなみに、クラス図 (その1) において、左側の多重度を 1 ではなく 0..1 で考えた場合、オブジェクト図 (その2) のような状況も考えられます。a、b いずれかからのみ参照をもつようなデータ構造ですね。このように、クラス図のだけでは情報はけっこう少なく、オブジェクトレベルで考えるといろいろなパターンを含む可能性があります。オブジェクト図 (その2) のように、a と b 両方からの参照をもつ c が存在しなくてよいのであれば、b から C のオブジェクトの追加をするのもとくに問題なくできるはずです。(要は、ユースケースによってはクラス図 (その1) でもいいわけです。)



というわけで、「b から C のオブジェクトを新たに追加する」というユースケースを実現するために、以下のようにしました。



オブジェクトレベルで考えると、オブジェクト図 (その3) のようになり、c' 経由で (c' のもつ配列ないしリストに) C のオブジェクトを追加することになります。これなら、a からも新たに追加されたオブジェクトが参照可能になります。
クラス図としてはクラス図 (その2) になるわけですが、オブジェクトレベルで考えていないとやはり辿り着きにくいと思います。



落とし穴、2つ目。
クラス図の関連や多重度をちゃんと描けるかです。



上のオブジェクト図 (その4) では、d が e の配列ないしリストをもつとともに、それとは別に e への参照を 1つもっています。いくつかの候補のなかから 1つを選択し、それに対して以後の処理を実行するようなユースケースです。処理のたびに候補から選択をするのはコストが高いので、選択されたものへの参照を別に保持しておくわけです。
クラス図だけを考えてると、D から E への関連を引っ張って終わりにしてしまいそうですが、オブジェクトレベルで考えると、オブジェクト図 (その4) となり、クラス図としてはクラス図 (その3) となります。多重度もちゃんと描きます。



クラス図ってどうも実装との間にギャップがあるように感じていましたが、オブジェクトレベルを意識して、ユースケースがそれで実現できるかという視点でしっかり考えていくと、ちゃんとコードに落ちるものなることが実際に体験できたと思います。


全体を俯瞰しながら大枠の設計を検討する際に、あまりに細部にはいってしまうのはまずいと思いますが、クラスの構成やそれらの関連あたりは細部とは言えないでしょう。そこをよい設計にするのには、やはり可視化されたほうが頭にも入りやすいですし、コミュニケーションにも都合がよいと思います。

今回の講義は、実装とのギャップを小さくした分析/設計の重要性とその有用性を体感できるものでした。



余談ですが、JUDE でオブジェクト図がかけました。
演習のときには、メモ用紙にぱぱっとオブジェクトを描き殴りながら考えていましたが、こんな風に清書する必要があるときにはよいです。オブジェクト図を描けるツールは少ないみたいなので... (リンクは矢印だとなおいい)

Q.「JUDEでオブジェクト図を描けますか?」というご質問。

答えは、「はい」です。JUDE/Community、Professional共に、オブジェクト図の描画が可能です。
クラス図を開いて、「クラス図」でサポートしているオブジェクト、リンク等の図要素を使用して描画してください。