ドメイン駆動設計のインターホンを押した

最近思うこと

DDD、ドメイン駆動設計。

カンファレンスのセッションや、書籍等でドメイン駆動設計をテーマにしているものが、数年前と比べて明らかに増えてきていると最近感じます。

Twitterのタイムラインにも毎日のように「DDD」という文字が流れてきます。

DDDのセッションを何回か聞いたことがあるのですが、

私の理解は「業務に詳しい人と協力し合いながら、現実世界をソースコードに反映させていく開発手法」という非常にふわふわとした理解でした。

そんなふわふわな自分に不安を覚え、エリック・エヴァンスのドメイン駆動開発(以下 DDD本)と実践ドメイン駆動設計(以下 IDDD本)を手に取ることにしました。

ドメイン駆動設計

ドメイン駆動設計とは何なのか。

DDD本の冒頭で以下のように述べられています。

先進的なソフトウェア開発者は、少なくともここ20年の間、ドメインモデリングと設計が重大なテーマであると認識してきた。 しかし、何をする必要があって、それをどのようにすべきかについては、驚くほどわずかしか書かれていない。 だが、明確に体系化されてはいないものの、オブジェクトコミュニティの底流として、ある哲学が出現してきている。 私はその哲学を、「ドメイン駆動設計」と呼んでいる

どうやら、ドメインモデリングという言葉が重要なキーワードという匂いがします。

IDDD本では以下のように述べられています。

DDDと呼ばれるソフトウェア開発手法がある。より高品質のソフトウェアモデルを設計する手助けとなる手法だ。 設計した結果が、そのソフトウェアの動作を明確に表すようにできる。 DDDでは、ドメインエキスパートとソフトウェア開発者が力を合わせて、業務のエキスパートのメンタルモデルを反映したソフトウェアを開発する。 これは決して「現実世界」をそのままモデリングすることではない。現状をそのままモデリングするのではなく、業務により役立つモデルを作る。

こちらでも「モデリング」というワードが出てきており、DDD本と同様に重要なキーワードという匂いがします。

ここで、何となく意味はわかるんだけど、具体的に説明してと言われると息苦しくなる「ドメイン」と「モデリング」という言葉について整理しようと思います。

ドメイン

ドメインという言葉を単純に調べてみると、「範囲、領域」という意味が出てきます。

DDD本では

すベてのソフトウェアプログラムは、それを使用するユーザの何らかの活動や関心と関係がある。ユーザがプログラムを適用することの対象領域が、ソフトウェアのでメインである。

IDDD本では

ドメインとは、広い意味でいうと、組織が行う事業やそれを取り巻く世界のことだ。

と、説明されている。

上記の説明から、ドメイン駆動設計におけるドメインとは「ソフトウェアが解決しようとしている問題領域」かなと理解しました。

モデリング

モデリングとはなんでしょう。

我らがwikipedia様を見てみました。

モデリング(英: modeling)は、広義の意味での模型(モデル)を組み立てる事を言う

モデルを作成することと一先ず理解することにしました。

では、モデルとはなんなのでしょうか。。。

調べてみると、

問題とする事象(対象や諸関係)を模倣し、類比・単純化したもの。また、事象の構造を抽象して論理的に形式化したもの。

DDD本を読んでみると、

選び抜かれてシンプルにされ、意図的に組み立てられた知識の表現形式

('・_・`)

なんだか難しい表現が並んでいると感じました。

何かしっくり来ないな〜、と思いながら調べていると「DDDのモデリングとは何なのか、 そしてどうコードに落とすのか」資料 / Q&A - little hands' labというスライドに出会いました。

こちらに記載されていた、

問題解決のために、物事の特定の側面を抽象化したもの

という表現が私には一番しっくりきた表現でした。

抽象化でググってみると

「思考における手法のひとつで、対象から注目すべき要素を重点的に抜き出して他は捨て去る方法である。」

と出てきます。

私の今の所の理解では「モデルとは」と問われた時の回答は

問題解決のために、物事の側面で必要な物だけを抜き出したもの

となりました。

モデルが私の中で上記の表現になったため、ドメインモデルは

ソフトウェアが解決しようしている問題領域内の物事の側面で、必要な物だけを抜き出したもの

といったことになるでしょうか。

DDD本やIDDD本ではドメインエキスパートと呼ばれる、ドメインについて一番詳しい人と話を重ねあいながらドメインモデルを作り上げる必要があると述べられています。

ドメインモデルを共に作成し、それを実装に反映させていく。

ドメインモデルと実装を密に結びつけることが重要になります。

ドメインモデルが変更されたら実装が変わる。

この辺りから、私が当初ざっくり理解していたことがなんとなくですが、鮮明になってきたような気がします。

ドメインモデル

では、ドメインモデルを表現するにはどうすれば良いでしょうか。

DDD本ではドメインモデルを表現する3パターンが紹介されています。(IDDD本では、戦術的モデリングツールと題して紹介されている)

  • エンティティ
  • 値オブジェクト
  • サービス

ドメインモデルを表現するパターンを明確に区分けすることで、ドメインモデルの意味が鮮明になり、実際に実装できるドメインモデルが作成できるようになります。

それでは、それぞれのパターンを見てみたいと思います。

エンティティ

同一性によって定義されるオブジェクトはエンティティと呼ばれます。

同一性の定義を調べてみました。

Aが異なった状況においても常に同じものであり,同じものとして認められるとき,A は自己自身と同一である。このとき A=A において同一性が成立しているという

よく同一性の例で目にするのが人間や会社かなと思います。

5歳の人間が25歳になっても、別の個人としては扱われません。身長が伸びても別の個人としては扱われません。 つまり、姿や形が変わっても、変化前と同じであるため、同一性によって定義されるオブジェクトと言えるでしょう。

エンティティは各オブジェクトを識別する手段を定義する必要があり、識別するための属性は一意なものでなければいけません。ここが値オブジェクトとは異なる点です。

値オブジェクト

同一性を持つものはエンティティと呼ぶと述べましたが、同一性を持たないオブジェクトは値オブジェクトと呼ばれます。 そのオブジェクトが何であるかが重要であり、どれなのか、誰なのかは問わないオブジェクトです。

ある概念が値であるかどうかを判断するときには、その概念が以下の特性を持っているかどうかを見極める必要があるとIDDD本では述べられています。

  • そのドメイン内の何かを計測したり、定量化したり、あるいは説明したりする。
  • 状態を不変に保つことができる。
  • 関連する属性を単位として組み合わせることで、概念的な統一体を形成する。
  • 計測値や説明が変わった時には、全体を置き換えられる。
  • 値が等しいかどうかを、比較できる。
  • 協力関係にあるその他の概念に、副作用のない振る舞いを提供する
サービス

ドメインにおける重要なプロセスや変換処理がエンティティや値オブジェクトの自然な責務ではない場合、その操作はサービスとして定義します。

集合に対する優先度の判定、パスワードの暗号化、オブジェクトの重複確認等、エンティティや値オブジェクトに振る舞いとして持たせてしまうと不自然になってしまうことがあります。

不自然な振る舞いをエンティティや値オブジェクトに持たせてしまうと、オブジェクトの概念が明確でなくなってしまいます。

では、サービスとしてエンティティや値オブジェクトに振る舞いを持たせるべきでないと判断する条件はあるでしょうか。

IDDD本では以下の3つが挙げられています。

まとめ

まだまだDDDの入り口の門を開けたところであり、抜け落ちている所ばかりだと思いますが、記事を書く前の自分よりかはDDDに対しての理解が進んだと思うことにします。

淡々とドメインモデルを表現するパターンを書いてしまったので、次はコードを交えて記事を書きたいな...