無限大な夢のあと

テニスとアニメが大好きな厨二病SEのブログ

Domain-Drive Design Quicklyを読んで(自分用メモ) その1

DDD導入研修の課題として、下記の書籍「Domain-Drive Design Quickly」を読むことになりました。
Domain Driven Design(ドメイン駆動設計) Quickly 日本語版
本文章は上記の日本語訳の資料を引用させて頂きます。


ただ漠然と読んでいるだけだと、頭を通りすぎていきそうなので、自分なりに要点や響いた箇所、メモを残しながら読んでいこうと思います。
※とはいえ、約80ページしかないものではありますが。

DDDの世界への第一歩を踏み出します!

・0.イントロダクション

ソフトウエアの設計は芸術です。したがって芸術と同様、厳密な科学のように
定理や公式を利用して教わったり学んだりできません。私たちはソフトウエア
の作成過程全体に適用できるような、原則や技法を発見することはできます。

芸術。まだこのレベルまでは遥かに至っておりませぬ。。


・1.ドメイン駆動設計とは何か

ドメ インはとても多くの情報を含んでいるので、すべてをモデルに取り込めません。 また、ドメインの大部分は考慮する必要さえないでしょう。こういった取捨選 択自体が大きな課題となります。何をモデルに取り込み、何を捨てるのか。こ れが設計作業であり、ソフトウエアの作成です。銀行業務システムはきっと顧 客の住所録を保持するでしょうが、顧客の目の色は無視します。もっともこれ はわかりやすい例です。他の場合はこれほどわかりやすくないでしょう。

この取捨選択こそが難しいのである。

モデルはソフトウエアの核ですが、これを表現し他人に伝える方法が必要です。 私たちは一人で作業するわけではありません。上手に、正確に、完璧に、曖昧 さを排除して、知識と情報を共有しなければなりません。これにはいくつかの 方法があります。ひとつは図による表現、すなわちダイヤグラム、ユースケー ス、スケッチ、絵などです。もうひとつは記述による表現、つまりドメインに ついての見通しを文章で記述する方法です。そして独自言語で表現する方法も あります。ドメインについての特定の問題を伝達するために私たちは独自の言 語を作成することができますし、そうするベきなのです。これらの詳細は後述 しますが、もっとも大切なのは「モデルを他人に伝えなければならない」という ことです。

「モデルを他人に伝えなければならない」。どのような手段であれ、これが一番大切。

この本はドメイン駆動設計の原則を説明します。この設計原則を適用すれば、
どのような開発過程であれ、その能力を十分に発揮してドメインの複雑な問題
に対して継続的にモデリングし、実装できるようになります。ドメイン駆動設
計は設計と開発を兼ね備え、どのように設計と開発が協調すればよりよいソフ
トウエアが出来上がるのかを示しています。優れた設計は開発を加速させ、開
発からのフィードバックは設計の精度を高めるでしょう。

「優れた設計は開発を加速させ、開発からのフィードバックは設計の精度を高めるでしょう。」
より設計と開発側を結びつけることにより、ソフトウェアの複雑性に立ち向かうということかな。
最近、読んでる下記の書籍で紹介されている原則でも、大まかにはソフトウェアの複雑性に立ち向かうためのものが多い。



・2.ユビキタス言語

ドメイン駆動設計の核となる原則は、ドメインモデルに基づく言語を使うこと
です。ドメインモデルはソフトウエアとドメインが出会う場所にあるのですか
ら、共通言語の基盤として適切です。
共通言語の拠り所としてドメインモデルを使います。そしてこの言語をコミュ
ニケーションに、さらにはコードにも使うようにチームのメンバに要求しまし
ょう。知識を共有しドメインモデルを構築しているあいだにも、チーム内では
レビューをしたり文書や図を作ったりします。どんな形態のコミュニケーショ
ンであれ、常にこの言語で表現しましょう。このような性質からこの言語は
「ユビキタス言語」と呼ばれます。

今までの現場であったような業務に関する共通言語とは正確には違い、ドメインモデルに基づく言語を「ユビキタス言語」とすると。

ユビキタス言語を創造する

この困難な作業に取り組み始めるには、チームのすべてのメンバが共通言語を
作らなければならないと自覚し、重要な点に常に注目するように気をつけ、必
要なときはいつでも作成した共通言語を使うようにします。このような作業の
ときには、独自の専門用語を可能な限り使わないようにします。そしてユビキ
タス言語を使いましょう。ユビキタス言語は明確に、そして正確に意思伝達を
する手助けをしてくれるのですから。

ここは、実際の設計時には特に意識していきたいところ。
いきなり実践ではできないから、ここを何かしらの方法でトレーニングしていきたいな。

もちろん、コードを使ってコミュニケーションをすることも可能です。この方 法はXPプログラミングのコミュニティで広く支持されています。丁寧に書かれ たコードはコミュニケーションにとても適しています。しかし、例えばコード を読むことで、メソッドが表現する振る舞いが理解できても、そのメソッド名 がその振る舞いと同じくらい明瞭に理解できるでしょうか。テストのためのア サーションは、アサーション自体の内容を十分に伝えてくれますが、変数名や コードの構造全体については何か伝えてくれるでしょうか。すべての挙動を一 目瞭然に教えてくれるでしょうか。コードは正しく振る舞いますが、必ずしも 正しい表現をするわけではありません。コードを使ってモデルを表現するのは とても難しいことです。

コメント書きすぎても保守コストが高いので、現実問題どれだけわかりやすくしてもそうだろうなと実感。


3.モデル駆動設計

3-1.モデル駆動設計の基本要素

業務ドメインを中心に据えたソフトウエア開発手法の重要さを強調
しました。ドメインに深く根ざしたモデルをつくることがとても重要であり、
そのモデルは、ドメインの中心にある概念を正確に反映するべきだと説明しま
した。「ユビキタス言語」はモデリングの作業全体を通して、ソフトウエア開
発者とドメインの専門家とのコミュニケーションをとても楽にします。また、
モデルに取り込むべきドメインの中心概念の発見にも役立ちます。モデリング
の目的は、よいモデルを作成することです。そして次は、モデルをコードとし
て実装していく作業です。ソフトウエア開発においては、この作業もモデリン
グと同様に重要です。すばらしいドメインモデルを作成しても、コードの中へ
正確に移植できなければ、品質の悪いソフトウエアになってしまいます。

前章までの振り返り。
頭の整理のためにメモとして残しておく。

どのようなドメインでも様々なモデルで表せます。そしてどのようなモデルで
も様々な方法でコードに落とし込めます。どんな問題にもひとつ以上の解決方
法があります。ではどの方法を選べばいいのでしょうか。よく分析されている
正確なモデルが、必ずしもコードでそのまま表現できるモデルであるとはかぎ
りません。それどころか、ソフトウエア設計の原則を無視した実装になること
もあるでしょう。原則を無視するのは勧められません。重要なのは簡単に、そ
して正確にコードに落とし込めるモデルを選ぶことです。ではここで基本的な
質問です。私たちはどのような手法でモデルからコードへ変換するのでしょう
か。

今までやっていたのは、例えばレシートからモデルを考えるのやった時には、名詞に着目して用語を抜き出してそこから関係性を記述したくらいか。
手法の名前は忘れました。

この方法の主な問題点は、アナリストがモデルの欠点や複雑な点をすべて予見 できないことです。アナリストはモデルの一部の構成要素は詳しく分析しても、 残りは十分に分析していないかもしれません。このため、とても重要な細部が 設計や実装の段階になって初めて見つかってしまいます。仮にドメインを正確 にあらわしたモデルを使ってみれば、オブジェクトの永続化に深刻な問題があ ったり、性能が許容できないほど悪いことがわかるでしょう。

また、開発者は独自に決断をせざるを得ないことがあるでしょう。モデルを作
成した時には考慮していなかった問題を解決するために、設計を変更すること
もあります。モデルから抜け落ちてしまっている部分を設計するのですから、
さらにモデルとの関連性が希薄になります。

分析モデルの欠点の記述。
そもそも、完璧に近いものなんてそうそう難しい。

つまり、より良い方法はドメインモデリングと設計を密接にすることです。モ
デルを作成するときは、ソフトウエアとその設計を考慮するべきです。また開
発者もモデリングに参加すべきです。モデルに基づいた設計作業を後戻りする
ことなく進めるには、ソフトウエアを正確に表現するモデルを選択することが
重要です。コードが基礎になるモデルとしっかり結びついていれば、コードの
意味が明確になり、モデルもより適切になるでしょう。

一つの結論かな。
完璧な設計なんて難しいから設計への手戻りを許容すると。

コードを書く人はモデルをよく知り、モデルが完全であることに責任を感じる
べきです。そして、コードの変更はモデルの変更を伴うことを自覚しなければ
なりません。そうでないと元のモデルと無関係になるまで、コードとリファク
タリングしてしまうでしょう。また、実装に関心を示さないアナリストは、開
発中に初めて見つかった実装上の制限に興味を示さないでしょう。その結果、
モデルは実践に適したものではなくなります。
どんな技術者であれ、ドメインモデルの作成に関係するのであれば、いくらか
時間を割いてコードを触ってみなければなりません。たとえそのプロジェクト
を主導する役割を担っていても技術者であればそうすべきです。コードの変更
に責任がある者はだれでも、コードを通してモデルを表現することを学ばなけ
ればなりません。すべての開発者はドメインモデルについての議論に参加し、
ドメインの専門家と意見交換をする必要があります。プロジェクトのメンバは
様々な方法でドメインモデルの作成に関わりますが、彼らは実際にコードを触
る技術者とユビキタス言語を使って活発に意見を交換しなければなりません。

「モデルをよく知り、モデルが完全であることに責任を感じる。」
他の誰かが立ち上げたプロジェクトに入ることになることがほとんどなので、モデルの理解を深めつつ、修正時にはより気をつかわなければいけないと。

ドメインモデルを正しく設計に反映させるためには、ソフトウエアシステムを
部分ごとに設計します。そうすれば、ドメインモデルと設計の対応関係も明確
になります。また、ドメインモデルを見直して修正を加えることで、より自然
にソフトウエアを実装できるようにします。ドメインの詳細な内容をモデルに
表現しようとする場合も同様です。設計との対応関係が明確なモデルであるこ
と。より自然にソフトウエアを実装できるモデルであること。この二つを満た
すひとつのモデルが必要です。加えて、ユビキタス言語が十分に使われていな
ければなりません。

・「設計との対応関係が明確なモデルであること。」
・「より自然にソフトウエアを実装できるモデルであること。」
この二つを満たすことが必要。

ドメインモデルから設計に使われる用語を抜き出しましょう。また、モデルの
どの要素にどの責務を割り当てるのかも、大まかに考えておきます。コードは
ドメインモデルを表現するので、コードの変更はモデルの変更と同じです。そ
して、その変更の影響はプロジェクトのその他の作業にも、相応に波及してい
かなければなりません。

ここでいわゆるコード設計する形になるのかな。

実装とモデルを強く結びつけるためには、オブジェクト指向プログラミングの
ようなモデリングのパラダイムに基づいているプログラミング言語やソフトウ
エア開発ツールが必要です。
手続き型の言語はモデル駆動設計を十分にサポートしません。モデルの重要な 部分を実装するために必要な概念を提供しないからです。OOPC言語のよう な手続き型言語と同じ使い方ができると言う人もいます。そして実際にOOPの 機能を使えば手続き型言語と同じような使い方もできます。例えば、オブジェ クトをデータ構造とみなして、振る舞いを割り当てないようにします。そして、 振る舞いはファンクションとしてオブジェクトとは別に実装します。しかし、 こうするとデータの意味は開発者にしかわかりません。コードそのものが意味 をはっきりと表現しないからです。手続き型の言語で書かれたプログラムは、 ファンクションの集合として理解されます。プログラムを走らせれば、ひとつ のファンクションが別のファンクションを呼び出しながら処理を進めて結果を 出力します。このようなプログラムでは、概念的に関係のあるプログラムの要 素をカプセル化できません。また、ドメインとコードを対応づけるのも難しい です。
手続き型言語を使って簡単にモデリングし実装できる特定の領域もあります。 例えば数学です。ほとんどの数学理論は計算で表現できるので、ファンクショ ンの呼び出しとデータ構造を使って単純に処理を実行できます。しかし、複雑 なドメインは計算のような抽象的な概念を集めたものではなく、アルゴリズム の集合に単純化できません。したがって、手続き型言語は様々な種類のドメイ ンを表現するには役不足です。モデル駆動設計での手続き型言語の使用は推奨 しません。

「モデル駆動設計での手続き型言語の使用は推奨 しません」とのこと。

モデル駆動設計の基本要素がここから紹介されていくので、一旦別記事で紹介していきます。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

実践ドメイン駆動設計 (Object Oriented SELECTION)

実践ドメイン駆動設計 (Object Oriented SELECTION)