Mix Leap Study 特別編 - レガシーをぶっつぶせ。現場でDDD! コラボカンファレンスのメモ書き #mixleap #gendadeddd

yahoo-osaka.connpass.com

最近社内のドメイン駆動開発系の読書会を二つ掛け持ちしてる人です。東京で同じカンファレンスがあって行きたかったなーと思ってたところ、大阪でもやると知って思わず登録、行ってきました。

raydive.hatenablog.jp

本当にどの発表も面白く、泥臭さとそれでもやりきる話ばかりでとても共感と気づきが得られたのはよかった。惜しむらくは、下にメモ書きした発表の裏で行われていたハンズオンや見られなかった発表などが多く、それらの内容も聴きたかった。ワークショップの内容はbiglobe-isp/workshopmobile: DDD ワークショップ課題のパブリックリポジトリで公開されていたので、これを社内でモデリングしてコードに落としてみるとかやってみるのもいいかなーと思ったりしている。他にもいくつかやってみたいことを思いついたので、どこかにメモっておこう。

OP

  • 経産省のDXのレポート
    • 変更が容易でないので大変なことになる
    • DDDでこれらの課題に立ち向かっていく
  • ❎綺麗な理論 ⭕現場のドロドロ感

ドメイン駆動設計という設計スタイル

  • 増田 亨
  • 基調講演
  • 現場でやってることのっこだわりポイント
  • 設計スタイルの選択
    • 関心の分離は原則、でもどうやる?
    • モジュール構造の考え方 プログラムの単位でどう作る?
    • 20:80の捉え方(パレードの法則)どこを頑張るか
    • ビジネスルールに基づく計算と判断のロジック、ビジネスルールに登場する値の種類に注目して独自の型を定義してロジック整理<=ここが大事
    • ここができてなかったら納期を遅らせても……バトルは起きる
  • ドメインロジックに焦点を合わせる
    • ドメインオブジェクトモデルの周りにトランザクションスクリプトのようなものを並べる => 割とめんくさいことはある(インピーダンスミスマッチはある)
      • でも手間はかけてもやる価値はある
    • 実践:ドメイン知識を学び続ける、コード表現の継続的な改善(エヴァンス📙に書いてあるやつ)
    • 増田さんの現場ではドメイン知識、ドメインロジックという言葉は使ってない -> ビジネスルール、ビジネスロジック
    • ビジネスロジックはビジネスルールに基づく計算と判断のロジック
    • ビジネスルールはビジネス活動を制約し促進する決め事
      • 非常に曖昧な論理的でないもの、過去の意思決定の積み重ね、通過点
      • わかりみしかない
    • 変更容易性という言葉の違和感
      • バラした方があとで組み立てやすいぐらい
    • ドメイン知識を広げる
      • 要求の意味がわかる
      • 関係性や構造が見える
        • エンジニア的に納得感がある
      • 補完力と提案力がます
        • ドメインエキスパートからは出てこない!関心がない!
      • 時間とともに変化し続ける => 学び続ける必要
      • 最近機能ベースでしか考えられてないんじゃないかと、自社を振り返って思う
  • 開発環境での実験結果と考察
    • コード書かない人
      • 書かない人の関心の文脈で見せる、丸っと理解させるのは無理
    • どの程度入出力にドメインの型が出てくるか
  • ビジネスルールの基礎知識
    • 文書化されたビジネスルール
    • 顧客の利益 vs 自社の利益
    • 競争戦略とビジネスルール
    • ビジネスルールの階層構造
    • これらはドメイン層のパッケージ構造の設計
  • コードで表現する基本テクニック
    • Fact, Rule, Goal
    • 独自の型を定義する
      • 納期の日付なのか、キャンセル可能な日付なのかなど
    • Domain modeling made functionalではOOなDDDでは…みたいなことを書いてあったが、増田さんが行き着いた先はだいたい同じような気がする
    • 暗黙的なif文 -> java enumを使ったコードに帰る -> ぎこちなくなったらリファクタリング、区分ごとのロジックを集める

DDDのモデリングとは何なのか、そしてどうコードに落とすのか

  • 松岡 幸一郎
  • モデリングをどうやるのか
  • DDDでのモデリングとは
    • DomainLanguage.com
    • 問題解決のために物事の特定の側面を抽象化したもの
  • ドメインモデル:ドメインの問題を解決するためのモデル
  • データモデル:データベースに何か永続化するためのモデル
    • DDDでは両方出てくる
  • 方法
  • なぜユースケース図?
    • 具体化・言語化したい(どこまでしたいかなど)
  • ドメインモデル図
    • クラス図の簡易版
    • 集約の範囲
    • 結構シンプル
  • まずは一人の人がモデリングを作ってみて横展開するのがおすすめ、形から入っていく
    • これはそうかも、わかりやすい
  • 属性のみの定義(ドメイン知識ない状態)からリファクタリングしていく
  • スライド参照
  • アプリ層にあるロジックをドメイン層に持っていくようにする
  • setterをなくす、コンストラクタしか通らないことを保証する
  • 抽象化の成功
  • 現場での実践
  • 原理からよりお手本からの方が難度が低い、イメージしやすい
    • これは大事
  • ORMはオブジェクトとテーブルが1:1になってるのはおすすめしない
    • わかるわ
  • モデリングの時間は30分ぐらいが限度
  • 集約とDBトランザクションはやってみて色々変えていく必要ある
  • トランザクションの管理は実践DDDでトランザクションをチェック
  • EntityからRepository呼ぶのはあんまりよくない

現場でドメイン駆動設計を広げるには何をすれば良いか?

  • 安西 剛
  • BIGLOBEでやってきたことの話
  • ディスカッションしながらやる
  • 安西さんのストーリー
    • 2010年、BIGLOBEは丸投げの会社 元請けに投げる人たち
    • 内政でWeb開発
    • アジャイルスクラムを必死に勉強 => ちゃんとリリースした!
    • 巻き込んで文化が変わる
    • 設計できない独自言語による実装 ナニモワカラナイ
    • DDDが良いらしい => 増田さんを読んでみた(期待はしてなかった、大企業でやってくれたらラッキーぐらい)
    • 増田さん「やる気あるんだと驚いた」
    • プロジェクトを勝手に立ち上げ、1回目は失敗
    • 2回目でリリース
      • なんで許されたんだろう、1回目で失敗したらやめろと言われそうなものだが
      • 懇親会で聞こうと思ったが、聞けず……残念
    • 技術的負債が根深いところだったけど、広がっていった
    • 無視される、理解されない、反対される
    • 仲間を見つめて一歩一歩進めていった
  • 自分のストーリーが大切
  • 誰もやってない
    • 一人でやる
    • 勝手にプロダクトコードに入れる
      • 強い
  • 仲間を選択する
    • わからない人は巻き込まない
  • 広げる
    • 勉強会を行う
    • 上司を味方につける
    • 有識者に教えをこう
    • 自然と組織で公認となる
  • チームから組織
    • いきなり全体でやらない
    • 暖簾分け方式
    • 失敗しても影響の少ないところから
    • 組織の2割の人数を目指す
  • コードに対するアプローチ
    • 整理整頓する、分ける、名前をつける
  • リファクタリング
    • 増田さんClean codeみたいなこといってる
  • 動かないと始まらない
  • 現場によって答えが違う
    • うちだとどうすべきか?

抽象的な教えを試行錯誤しながら解釈した DDD の実践レポート

  • ほげさん
  • 突然のDDDチーム
    • 大変そう
    • 何させたがってるかわからない -> 抵抗感
  • 「君のDomain層からは業務を感じない」
  • 名詞を探す
  • ドメインがスカスカ -> 集めてくる
  • 処理順とか条件分岐とかDB更新がドメインだと思っていた
    • 絵から読み取れない情報が多い
    • やっぱりあかん
  • ドメインだと思っていたものがドメインじゃなかった気づき
  • 動詞を探す
    • 同じこといってる人いた気がする
    • dmmfだとワークフローとかそういうのかな?
      • イベントか、コトだ
  • 境界を決める
    • Domainあった外の都合を排除
    • 知りすぎてるドメインを切断
    • 変わりやすい方に依存している線を逆にした
  • 理解
    • モデリングするとER図ができる
      • Domain -> infraへの依存関係がある、よろしくない
      • 変更頻度が違う
  • コードからここまでたどり着くのすごい
  • テストコードは必要か?
  • システムのエラーとビジネスのエラーは分けたい
  • エヴァンス本ほとんど読んでない
    • コードからやっていった

過去の失敗例から再考するモデル駆動設計

  • かとじゅんさん
  • チケット料金モデリングは社内でやってみてもよいかも
  • 軽量DDDの鋼材
    • トランザクションスクリプト亜種
    • ユビキタス言語を共有したつもり
      • 外向けの通訳が必要になった
      • 分析と実装の単一モデルになる前提じゃなかった
        • エンティティはテーブルではない……が勘違い
        • ドメインモデル貧血症
          • 合計金額の計算が外に出てる……
      • うちは軽量DDDだなぁ……戦術的パターンを適用しただけ
    • アプリケーションサービスは進行役(by 増田さん)
    • 無駄に英語使うより日本語使った方がわかる
    • まとまってないといけないものが、テーブルの都合で分けられる😨
    • getterしかないオブジェクト、辛い
  • 言語とモデルを作ってソフトウェアに反映する
    • スライド参照
    • 自分たちは自分たちが作ってるものの使い方や意味を知っているのだろうか
  • 分析から実装に反映、分析を見直し、要件を見直し。行ったり来たりする。
  • ドメインモデル貧血症対策
    • オブジェクトは自己防衛する、不正な値は扱わない
    • コレクション型はそのままつかない、ドメイン固有型を介して使う
      • List<CartItem>にしがち -> CartItemsにする
    • 値オブジェクトのまま比較や計算ができるようにする
  • スケーラブルな設計
    • ドメインオブジェクトと言語の体系が一致してる
    • ドメインの上の値はただのプリミティブ型ではない、制限などルールとそれに基づく計算能力を持つものである
      • dmmfだとこの部分を型に集約させている
  • 集約の境界定義の善し悪し
    • スライド参照
      • 全部集約にするのか、集約は一つなのか
    • 全てが集約だと→アプリケーションサービスで悪いことに
      • アプリケーションサービスにドメインの知識が流れ出てくる
      • 試行錯誤してやってみたが結果整合性で不整合な状態が観測できる -> ビジネス的な要件でダメだった
      • 集約は一つに
    • 細かく分けすぎると貧血症になりやすい
    • ユースケースだけでは境界定義が決まらない
    • でかいとI/Oのレイテンシがでかい
      • そもそも説明が難しいモデルは実装が大きくなる、I/0のコストもでかくなる
    • 振る舞いにフォーカスし小さい主役を実現するには、クエリ責務を他に考える CQRS
    • Event Storming + 値オブジェクトモデリング
  • PDR
    • PDCAは工場の歩留まりをあげるためのもの