いものやま。

雑多な知識の寄せ集め

ソフト開発における「設計」とは何なのか。(その11)

前回はアジャイル開発に関する話や実現可能性の話を書いた。

今回はプロセスの話ではなく、ソフトウェアをどう考えて設計するといいかについて。

オブジェクト指向分析設計

今ソフトウェアの設計の話というと、ドメイン駆動設計(Domain-Driven Design, DDD)が流行っている感じはある。

ただ、どうにもDDDの本来の目的(ソフトが価値提供する領域(ドメイン)の知識をドメインモデルとして表現し中核に置くことで、価値提供の現場とのギャップをなくそうとしている)とはズレて、小手先のテクニックや紹介されているアーキテクチャの真似事に陥ってしまっている感じも。 根底にある思想の理解は難しいけど、やることのマネならなんとなくできてしまうからねぇ。

それと、一番肝心のドメイン知識をどうやって得るのかという部分についてはあまり語られていないというのも大きい。 「DDDやってみたいけど、ドメインモデルが抽出できない」というのもよく聞く。

そもそもの話として、オブジェクト指向的な考え方でなくフロー指向的な考え方をしてると、ドメインモデルをクラスとして表現するという発想ができないので、オブジェクト指向的な考え方ができてることは前提としてある (オブジェクト指向とフロー指向については『オブジェクト脳への一歩』というLTをしてみた。 - いものやま。や自分の同人誌『オブジェクト・ウォーズ』を参照)。 この前提がまずできてない人も多い印象・・・

それを抜きにしても、どうやってドメインモデルを抽出していくのかという「やり方」のは説明が必要だと思う。

実はそのあたりの「やり方」の話は、ソフト開発における「設計」とは何なのか。(その8) - いものやま。でも少し書いたけど、オブジェクト指向分析設計(Object-Oriented Analysis and Design, OOAD)で語られている。

オブジェクト指向分析設計について知りたい場合、次の本が楽しく読めると思う:

ただ、絶版なんだよなぁ・・・コード例が古いというのもちょっと難点。 デザインパターンは第2版が出たので、これもまた出るといいんだけど。

ユースケースから考える

さて、設計の出発点となるのは、ユースケース。 ここで、システムは何を顧客に提供するのか(そして何を提供しないのか)という境界を定めることになる。 また、システムが実際にどのように使われるのかや、その中で出てくる概念(ドメイン知識)を洗い出すことになる。

ドメイン駆動開発だと、このユースケースについて考えて分析するというプロセスが書かれてないんよね。

で、ユースケースを考えたあとにやりがちなのが、そのユースケースの流れをそのままコードにしてしまうということ。 これはとてもフロー指向的な考え方で、これをやってしまうとドメイン知識はどこにいるのか分からなくなってしまう。 トランザクションスクリプトと呼ばれるのは、これをやってしまった結果として生まれる。 とても自然な発想ではあるんだけど、ドメイン知識があちこちに散らばってしまったり、変更に弱いコードになりやすい。

じゃあ、ユースケースを考えたあとに何をやるといいのかというと、ユースケースに出てくる名詞(と動詞)に注目するということ。 それらはドメインに登場してくる重要な「概念」なので、それらを抽出して、その概念がどういったものなのか、データ(プロパティ)として何を持つのか、どういったデータが妥当なのか(不正なデータの規定になる)、何ができるのか(メソッド)、他の概念との関係性はどうなっているのかなどを分析する。 そうやって分析した結果として表現されたクラスにはドメイン知識が詰め込まれることになる。

また、それらの概念を使った「処理」というのもある種の概念となるので、それもクラスとして表現しておくといい。 どういった処理を行うのかという具体的な内容、知識がクラスの中に詰め込まれて、外部からはその処理を実行しろというキックだけ行えば、オブジェクトが適切な処理をしてくれるようになる。

あとはそうやって用意した部品を組み上げてユースケースを実現すればいい。 こうすることで、ドメイン知識の詰まったコードを生み出せるようになる。

で、実際の開発の場合、生み出すのはソースコードの差分なので、こうやって分析するのは今回開発or変更する部分についてだけとなる。 そして新しく作るクラスや変更の入るクラスが見つかったら、それを設計書に書いて、方針の確認をするといい。 こうすると、処理の流れといった詳細をダラダラと書くのではなく、ファイル構成やそこで実装されるクラスといった概念レベルでのチェックができたりもする。

今日はここまで!