2019-03-22 ドメイン駆動設計 本格入門 #DevLOVE
2019/03/22 に実施された [DevLOVE Premium第3回]ドメイン駆動設計 本格入門 のイベントレポートです。
●イベント概要
・毎月、特別な企画をあなたにお届け。それが「DevLOVE Premium」
2019年。DevLOVEでは、毎月1回、あなたに特別な時間をお届けします。
「DevLOVE Premium」と題したこの企画、各回に1つの技術テーマを設けて、普段は聞けない、コアでディープなイベントを展開していきます。
・第3回のテーマは「ドメイン駆動設計」
ドメイン駆動設計の考え方とやり方を、10年の実践経験を踏まえ解説します。
特に以下の内容を重点的に取り上げます。
・ドメインを隔離し、そこに焦点を合わせるとは、具体的にどういうことか
・他の設計スタイルと比較したドメイン駆動設計の特徴
・マイクロサービスアーキテクチャとの関係
・現在進行中の大規模な取り組みの事例
概要説明ではなく、開発現場にドメイン駆動設計を導入し、その効果を最大化するための勘所を実コードを使いながら解説します。
■ドメイン駆動設計 本格入門
増田 亨さん 有限会社システム設計 / ギルドワークス
●現在の取り組み
Java x Springに振り切って開発している
レガシーなシステムのDDD適用を手伝っている
●ドメイン駆動設計の考え方
・ソフトウェアの開発を楽で安全にするため
・エヴァンス本のまえがきとエピローグ
・ドメイン駆動設計でなぜつくるのか
きれいな上流設計になっていたが、実装は切り離されていた
役に立った、稼げるソフトウェアは作れたが
継続して成長と進化させることはできなかった
DDDを考えるときは、何年もの間というスパンで捉える
・ソフトウェア設計がうまく行っているかの指標は、変更が楽で安全か?
・変更を楽で安全にするために
関心の分離、モジュール構造の分離を工夫していく
●ドメイン駆動設計を理解する3つのキーワード
・ドメインロジック
ビジネスルール
・ドメインモデル
計算モデル(8割くらいのサブセット)
・オブジェクト指向
型指向のプログラミング
・ソフトウェアが複雑になる理由
ビジネスルールの1つ1つは単純
ルールを適用する条件分岐で複雑になる
どこに適用すれば、安全で楽になるかを考えるのは難しい
●複雑さと戦う準備
・入出力からビジネスルールの記述を独立させる
ドメイン層に複雑さを集めただけ
入出力のノイズがないぶん戦いやすくなる
他の層がシンプルになる -> 自動生成で良いのでは?
・トランザクションスクリプト
ビジネスルールがあちこちに分散して、重複する
機能単位の手順で書いたら、共通のビジネスルールを使うのは必然
●複雑さにどう立ち向かうか
・モデル
ソフトウェアでのモデルは抽象化というより分離
位的なA,B,C -> 一般的ななんとかとして説明できる
受注、発注 -> 注文
これには疑問
受注 extends 注文
発注 extends 注文
主の関心と、その他を分離して、捉え直す
全体を見て、ピントを合わせることを繰り返す
・計算モデル
ソフトウェアは入出力と計算でできている
計算モデルか、データモデルかアプローチの仕方がある
データモデルからアプローチしても、ビジネスの複雑さは解消されない
Fact-Rule-Goal
・型指向のプログラミング
プログラミング言語の型は汎用的。ビジネスルールに合わせて型をつくる。
Fact-Rlue-Goalで型の候補を捉える
毎回ゼロから作っていたら時間がかかる
設計パターン
値オブジェクト
ロジックを持ったenum
コレクションのカプセル化
・値オブジェクト
・どんなもの?
Factの表現手段
Ruleの置き場所
Goalの表現手段
・効果
値の種類を明示的に表現
ビジネスルールの記述が重複しない
-> 楽で安全になる
・加算、減算 と 乗算、除算 では性格が違う
金額同士の加算、減算は普通
金額同士の乗算は、たぶんない
金額同士の除算は、たぶん割合
・これがあったら便利そう は作らない
必要最低限を作って、必要になったら足せば良い。
・契約による設計
assertによる表明 より 型による表明 を進めている。
どちらも共通で、防御的なコードを書かない
nullは返さない文化を前提にして
事前条件、事後条件を型で表現
・不正なオブジェクトは生成しない
生成してしまったら、生成したやつが、外に出す前に破棄
・enumを使った区分ごとのロジックの整理
複雑性に立ち向かうための揚力な武器
区分を常に疑いの目で見る
・誤った区分体系の場合、enumにロジックを寄せるとコードが歪む
-> 区分を見直す
・コレクションのカプセル化
コレクションを操作する類似の記述が分散
バグの温床
-> 目的別のコレクションに操作も閉じる
●エヴァンス本のススメ
・DDDの情報は増えてきたけど流れている情報が、特定のパターンに偏っている
・エヴァンス本とIDDD本は個別のものもある
・エヴァンス本は通読するものじゃないw
●パターン
・エンティティは、計算から見ると脇役
・ブレイクスルーが起きている話題は、だいたい値オブジェクトの話
・集約は、DBの整合性ではなく、計算の整合性・一貫性
・リポジトリも、計算から見ると脇役
・ユビキタス言語は、あらゆるところで出てくる言葉
slackでの会話やコミットコメントにも出てくるはず
・境界づけられたコンテキストはつくることが目的ではなく、モデルが生まれる背景
・コンテキストマップは、計算モデルのマッピング
1つ vs 1ダース など、関心が違う
●エヴァンス本の全体を俯瞰して理解しよう
・1〜2部は、準備
設計のtipsが入っていたり
・3〜4部に入らないと変更を楽に安全にできない
3部は経験談で、ためになる
本を書いた経験から見ると、4部は怪しい
・3部:役に立つモデルの実践的な設計技法
9章:ビジネスルールを理解する
10章:表現を洗練する
・4部:大規模に長期的に取り組む
14章:準備
15章:コアのハイライト、隔離
16章:関係を共通理解にする
●責務のレイヤ
ポリシー、約束、運用、能力
事業の決めごとを、契約に従って、何かを、どうする
・ビジネスルール
契約、バリューチェーン、事業運営ポリシー
・約束
何を、どのくらい、いつ、いくらで、誰に
・能力
約束してよいこと、できないこと
・運用
約束の履行の監視と督促
約束違反が複雑性を生む
●レガシーに立ち向かう
・期待しても疲れるだけ
テーブルは更新できるデータファイル。ファイルころがし
命名規則、番号体系
使われていないコード
・実際に使われているデータが最大の手がかり
・目のつけどころ
区分体系
業務マニュアル、料金表などの導出ルール
・あるべき姿の中核を生み出す
できるだけ早い段階で、本番データで動かす
サブセットを増やしていくこともできる
-> 実現可能性が見える
・複雑さの確信に切り込む
区分体系の整理
「なぜこの組み合わせはないんですか?」の学びが大きい
・関係者に説明する は必要w
●マイクロサービスとドメイン駆動設計
くわしくは JJUG でw
・分割の軸
ビジネス能力
ドメインモデル
アクション指向
リソース指向
・これらを組み合わせる
主軸は何にして、補助軸の優先度を整理
・継続的に「分割の見直し」ができるか?
-> マイクロサービスはスケーラビリティを重視したときの特殊解なのでは?
●アプリケーション層の複雑さの分析と整理
・VETRO分析を分割に使う
Validation
Enrich
Translate
Routing
Operation
・Sagaでビジネス的なトランザクションを分割
serviceを組み合わせるように整理したら
アプリケーション層を整理できた
・事実の記録
NULLという事実はない
外部キー制約を考えると、事実の前後関係が見えてくる
-> HEADER, DETAIL関連は、別の事実と考えた方が良いのかもしれない
関数従属性を考えると肥大化しがち、発生時点でテーブルを分ける
・良い設計を目指すと、マイクロサービス化しやすくなる
・マイクロサービス化のトレードオフを考える
■感想
個人的に、エンタープライズな現場で長く過ごしているからか、レイヤのないトランザクションスクリプトの、泥団子なシステムの改善をサポートすることが多いです。
第一歩として、入出力とビジネスロジックの分離から着手していきますが、だいたいここで影響範囲の切り分けと、タスク分割ができるようになることで満足感が生まれてしまい、ビジネスロジック側のリファクタリングに入る前に勢いが止まってしまいます。
私も早く「enumにロジックを寄せて、歪みへの気付きからブレイクスルーを起こす」経験をしてみたいです!
今回も「そうですよね〜」と「ワクワク」をたくさん感じながら楽しくお話を伺えました!ありがとうございました!!
いいなと思ったら応援しよう!
いつも応援していただいている皆さん支えられています。