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

ラーニング・ツリー・インターナショナルの講座を受けています。
カンサス州立大学のコンピュータサイエンス学科の教授、水野 匡章先生が講師をされている講座です。
別件ではありますが、先生の講演資料として下記のものが Web で参照できます。米国での仕事経験に基づいたものですが、こちらも興味深い内容でした。

  • ヒューマンキャピタル 2008

ITアーキテクトの重要性とその育成方法 〜アメリカの成功事例から学ぶ〜

先生のお話のなかでもよく登場するのが、「Life is beautiful: ソフトウェアの仕様書は料理のレシピに似ている」の記事。あまりに納得のいく内容なので全文引用したいくらいですが、少しだけ... (それでも多いですが)。
先生も同じ想いを持っていて、強くアーキテクトの必要性を説いています。上の資料もその流れですね。

自信を持って言えるのだが、「どんなに優秀なエンジニアでも、決してプログラムを自分自身で書かずに良い詳細仕様を作ることは出来ない」という絶対的な法則があるのだ。私の知っている優秀なエンジニアは、皆それを知っており自ら実行している。もちろん、彼らはプログラムを書き始める前に大まかな設計をするのだが、十分な経験を積んだエンジニアは、その段階でのものが「仮設計」でしかないことを良く知っている。だから、その段階で詳細設計書を書くような時間の無駄使いはせず、すぐにプログラム(もしくはプロトタイプ)の作成にかかるのである。

実際にプログラムを書き始めて初めて見えてくること、思いつくことが沢山あるので、それを元に柔軟に設計を変更しながらプログラムを書き進めるのである。作っているプログラムが予定通りに動き始めてやっと、設計も完成に近づくのである。

世界を又にかけてソフトウェア・ビジネスをしている米国の会社は、MicrosoftにしてもGoogleにしても、この法則にのっとって、アーキテクト自らががプログラムを書いている。


(中略)


「自分でプログラムを書かない上流のエンジニアが詳細設計書を作り、下流のエンジニアがコーディングをする」という工程そのものが、根本的に間違っているとしか思えないのだ。

シェフがレシピだけ書いてキッチンにも立たないレストランには行きたくないし、ましてや自分で料理したこともないシェフが書いたレシピを元に作った料理がおいしいわけがない。

さて、講座のタイトルは、実践的オブジェクト指向分析・設計と実装というものですが、一連のプロセスを座学的に学ぶのではなく、かなり実装イメージが膨らむところまで分析/設計し、そして実装まで落とすのが特徴的だと思います。(この手の講座を受けたことはないので、これまでに読んできた書籍からの印象ですが。)


で、そのために講義開始の 1時間後くらいには、メモリ上のスタック、ヒープ領域の話になり、スタックフレームやオブジェクトの参照状況などの「基本」をたたきこまれます。ひさしぶりに Visual Studio の画面を見ましたが、ヒープメモリの中身や、スタックフレームが詰まれている状態がデバッグトレースでかなり見やすく可視化されるのはすごいですね。それにしても、この講座のタイトルでヒープやスタックの話が最初に登場するとは思わなかったです..。


クラス図での関連も、オブジェクトレベルでの参照を強く意識しながら描くように教えられるので、クラス図上での何気ない一本の線が実装上かなり大きな意味をもつことが理解しやすいです。間違った線 (関連) のせいで実装が複雑になり、メンテナンス性にも乏しく、パフォーマンスもよくないものになるのはままあることだと思います。

間違った線はよく設計されていないため (場合によってはいきなり実装から入ってしまったがため) に起きることが多く、UML レベルでは線一本の付け替えで済むものが、実装に入ってしまっているとなかなか付け替えに等価な変更はできません。だからこそ、オブジェクトレベルまで意識しつつ、しっかり分析/設計をし、多重度を含めたクラス間の関連を最初にしっかり決めるのが大事という話です。多重度を意識しないと、オブジェクト同士が m 対 n で関連をもつなんていう悲惨な事態が生まれやすいんでしょうね。


演習が多いのも特徴で、初日は自動販売機を分析/設計し、実装に落としました。バウンダリー (コイン投入口や選択ボタン、購入可能ランプや売り切れランプ、釣り銭切れランプなど) まで含めると 10 以上のクラスが登場してくるのでさすがにいきなりの実装は大変です。ちょっとずつ実装しながらってのもありでしょうが、やはり問題にぶちあたったときの設計の変更コストは大きく、下手をするとデバッグ地獄にはまってきそうな気配もあります。


演習を通じ、オブジェクトレベルを意識してクラス図を描き、クラス間 (オブジェクト間) の関連と、ファンクション名だけしっかり設計すると、たしかに手戻り少なく実装に落とし込めるように感じました。ファンクションの中身の詳細までは分析/設計の対象ではなく、あくまでオブジェクト間がどんなシーケンスでつながっていくかを把握するのに注力します。そして、それができたあとでファンクションの中身を含めて、機械的に実装に落とし込んでいきます。
もちろん、実装に落とし込みながら、再度設計を見直すことはあるでしょうし、一緒に開発するメンバーの経験や知識の度合いによっても、どこまで詳細に分析/設計するかは変わるでしょう。バランスは都度調整する必要がありますが、設計をあらわす共有ドキュメントが必要なのであれば (プロダクトレベルで不要なことはないと思いますが)、それを無駄にせず、手戻りを少なくできる武器にするのがいいというのは納得です。やはり関連構造の見直しはコードだけからだと大変ですし、可視化されていると見直しがしやすい上に、全体構造を踏まえてよい設計になっているのが "分かる" という安心感もあると思いました。



端的な表現にしてしまうと以下に尽きるのすが、手を動かす & 失敗経験がともなわないといまいちピンとこないですね。

  • 1. オブジェクトレベルで考える
  • 2. ユースケース実現の詳細度をあげる


うーん、なかなか言葉だけで表現するのは難しい..。だから数多あるこの手の書籍も苦しんでいるのでしょうか?
個人的にはかなりヒットな内容なので、そのよさをうまく伝えられるようがんばってはみたのですが... (講座の一部でいいんで youtube とかに流してほしいですね.. 広告費ゼロの宣伝なんだけどなぁ)


まだまだメモしたことはいろいろあるのですが、ひとまず明日もあるのでこのあたりで。 (^^;