dskst's diary

Life and Tech Blog

ドメイン駆動設計本格入門で学び、そして学びほぐされた #devlove

ドメイン駆動設計本格入門に参加してきました。

devlove.doorkeeper.jp

講師は増田亨(@masuda220)さんでした。

f:id:dskst9:20190324153527p:plain

概要説明ではなく、開発現場にドメイン駆動設計を導入し、その効果を最大化するための勘所を実コードを使いながら解説します。

とあるように、抽象の話ではなく具体を学ぶことができる講習でした。
以下、講習の中からとくにドメイン駆動設計にフォーカスして内容をまとめていきます。

www.slideshare.net

ドメイン駆動設計でなぜつくるのか

ドメイン駆動設計でなぜつくるのか。

ソフトウェアの変更を楽で安全にするため。 ドメイン駆動設計で変化や成長を呼び込むような設計になる。

逆を言えば、ソフトウェア設計がうまく行っているかの指標は「変更が楽で安全にできるか」と考えることができる。

3つのキーワード

  1. ドメインロジック: 複雑さの根源 -> ビジネスルール
  2. ドメインモデル: 複雑さをモデルで整理 -> 計算モデル
  3. オブジェクト指向: モデルと実装の一致 -> 型指向プログラミング

ビジネスルール

ビジネスルール自体が複雑ではなく、適用する条件による分岐が複雑である。

ビジネスルールの記述を別のモジュールに分離することで、モジュール群に複雑さが集中する。これだけでも、シンプルになる。

モデル

モデルはどこまで行ってもモデルなので現実ではない。
モデルを作るのは抽象というよりは分離ではないか。

ドメイン駆動設計では以下が考えとして大事になる。

  • 中核と周辺
  • 主軸と補助軸

モデルは、計算モデルとデータモデルで分かれる。
データモデルはソフトウェアの複雑さに立ち向かう軸ではない。 計算モデルこそビジネルルールである。

ビジネスルールのモデリング

Fact-Rule-Goal
事実(Fact)を表現し、Factを使った計算や判定のロジック(Rule)により、知りたいこと(Goal)を表現する

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-38-638.jpg?cb=1553227323

値オブジェクト

プログラミングの表現が、ビジネスルールそのものになる。
値の計算とかで”あったら便利”というものは絶対に作らない。今、確実に必要なものだけを抑えておくこと。

値オブジェクトを用いることで契約による設計を行うことが容易になる。

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-42-638.jpg?cb=1553227323

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-45-638.jpg?cb=1553227323

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-46-638.jpg?cb=1553227323

契約による設計
  • クラスを使う側の責任:引数の型
  • 計算を提供するクラスの責任:返り値の型

防御的な検査コードを書かない。
nullを渡さない、返さない。
不正な値を持ったオブジェクトを生成しない

暗黙のビジネスルールの明文化に繋がる。
たとえば、Quentityという型があれば、それに負の値は入らないなど。

ロジックを持ったenum

区分体型の問題の発見と改善が進む。

区分をenumに落とすと、コードが歪む。 歪みに気づくことで区分のリファクタリングを行うことができる。

コレクションのカプセル化

コレクションをカプセル化することで、コレクション操作が隠蔽されてビジネスの関心事が全面に登場する。

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-56-638.jpg?cb=1553227323

エヴァンス本のススメ

通読するな。パターンをひとつひとつ理解しても役に立たない。

  • パターンにの背景にある動機を理解する。
  • パターンとパターンの関係を理解する

パターンについて

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-63-638.jpg?cb=1553227323

  • エンティティ: 入出力なので主役ではない。
  • ドメインサービス: ドメインサービスも、ドメインとして表現できるのではないか。

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-64-638.jpg?cb=1553227323

  • ユビキタス言語: 尺度あって、共通言語として存在することはほぼない。大切なのはあらゆるところにその言葉出る事が大事。
  • 境界づけられたコンテキスト: コンテキストを切ることがゴールではなく、背景にあるコンテキストがどうなっているかを正確に捉えた上で、それが適切なのか、コンテキストを分けたほうがいいかを考えることが大事。
  • 継続的な統合: オールグリーンではなく、チャットやコミットログなどで、ビジネスルール、言葉が使われているかということが大事。言葉として、言葉の理解としての整合性が大事。
  • コンテキストマップ: データ入出力とかではなく、計算モデルとしてのマッピングである。たとえば、数量というのがコンテキスト単位で違うなどという範囲を表現する。

責務のレイヤー

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-85-638.jpg?cb=1553227323

債務レイヤーとビジネスルールを理解することで、ドメインを見つけることができる。
約束違反の決めごとが難しくしているが、そこまで理解するといい。

マイクロサービス

マイクロサービスは複雑さを持ち込むことになる。

ドメイン設計で関心の分離とモジュール構造の改善を積み重ねると、アプリケーション層クラス・メソッドが安定する。 データベース設計が安定する。

ここからマイクロサービス化を検討するといい。

アプリケーション層の複雑さ

以下のような分析方法でアプリケーション層を分析していくと整理しやすい。

VETRO

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-119-638.jpg?cb=1553227323

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-120-638.jpg?cb=1553227323

Saga

https://image.slidesharecdn.com/essentials-of-domain-driven-design-190322040009/95/-122-638.jpg?cb=1553227323

データベース設計

変更が楽で安全なデータベース設計を。

  • 事実を記録を徹底する
  • 事実に基づきテーブルを分割する
  • イミュータブル、ミュータブルを取り決める
  • テーブル、スキーマ、データベースと発展させる

さいごに

ドメイン駆動設計をテーマとして、エヴァンス本の読み方、レガシーへの立ち向かい方、マイクロサービスなどとても深い学びを得ることができました。

増田さんの著書である「現場で役立つシステム設計の原則」もおすすめです。
とてもわかりやすく、ドメイン駆動設計を実践していくということができます。

ドメイン駆動設計はソフトウェア開発の基礎になっていると感じています。
難しいと捉えてしまいますが、さまざまなアプローチで学ぶことにより少しずつ理解することができました。

学び方、
本の読み方ひとつとっても、先入観を捨てなければならない。

そうか、"学び方"をunlearnしなければいけないな。と気付かされたよい一日でした。