mono(0w0)ログ

読んで、体験して、自分でやってみた記録

Mix Leap Study 特別編 - レガシーをぶっつぶせ。現場でDDD! コラボカンファレンス に参加した

現場でDDDを取り入れて2年くらいになるので半分答え合わせ、半分もっといい方法がないかなという期待で参加しました。

基調講演 ドメイン駆動設計という設計スタイル

www.slideshare.net

増田 亨さんの基調講演。 自分がDDDを始めるきっかけになった方ですし、始めた時もメンバーにこの本の通りに作るからといって始めたくらい密かにお世話になった方です。

設計スタイル

ドメインオブジェクトに振り切った設計というのが印象的でした。 増田さんの本を参考にDDDを始めて、最も効果が大きかったのがここに現れています。 入出力を切り離すことで得られる恩恵はとても大きい。 クラス数はとても多くなるけれども一つのクラスはとても小さい。 循環的複雑度も最大で10くらい(Checkstyleで縛りいれた)になっている。 一つで何やっているかはとても良くわかるけど、全体として何やっているかを理解するのはちょっと手間。

  • 関心の分離
  • モジュール構造
    • トランザクションドメインオブジェクト
    • 手間をかけるので無駄なことをやっていると思われる
    • 大きなメリットを得られることを強調
  • 20:80のとらえ方
    • ドメインロジックの設計が80%に影響する
    • ビジネスルールに登場する値・種類に注目
    • 現場で戦いが起きる。負け戦だけど

ドメインロジックにフォーカス

この章で印象に残ったのは、「ユーザーは詳細な仕様に関心がない」ということ。 「そのために詳細仕様を補完し提案する。ユーザーからフィードバックをもらう。」の部分では首肯しまくり。

ちょうど最近、メンバーがシステムの挙動についてユーザーにヒアリングする場面があり、それはユーザーに聞くのではなく、「この仕様でいきますが問題ありませんか」という提案型に変えようとアドバイスしたばかり。聞いても明確な答え得られないから。 他にも「ビジネスエキスパートから出てこないことが、契約書、利用規約、業務規約などから読み取れる。」などのノウハウも。

  • ドメインの知識を学び続ける
    • 要求の意味が理解できる
    • 関係性や構造が見えてくる
    • 詳細仕様の補完力と提案力が増す
    • 時間とともに変化し続ける
  • ドメイン知識のコード表現を継続的な改善
    • fact、rule、goal
    • 独自の型を定義
      • 構造と秩序、バグ減らす
      • 名前がコードの意図を表現
    • 可読性の向上とコードの追跡しやすさ向上は実感しやすい
  • ドメインロジック → ビジネスロジック
  • ドメイン知識 → ビジネスルール
  • 学び方

現場での結果と考察

ここも首肯しきり。 個人的な実感としては、長い間トランザクションスクリプトに馴染み切った人ほど脱却に時間がかかる。最初に躓く。 一方、若い人は素直に受け入れる。でも、その先に完全に思考を切り替えて定着させられる人はまた一部。 長いことやっているのでこのメリットをどれくらい感じているかメンバーに聞いてみようと思った。

  • 考えて書く人
    • 伝わる
    • 入出力フォーカス設計スタイルは個人差
  • 書かない人
    • 言葉では無理
    • 全員に伝えるのは無理く
    • 相手の見たいものを見せる
  • パッケージ構造に意識が向けられたらレベルアップの証拠

この辺が放置気味なので今後の課題。

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

little-hands.hatenablog.com

松岡 幸一郎さん

モデリングとは

  • モデル:文脈によって異なる
  • DDD reference参考
  • ドメインモデル
    • 問題解決のためのモデル
  • データモデル
    • 永続化のためのモデル

どうやってモデリングするのか

little-hands.hatenablog.com 参考サイトにも記載されていますが、個人的に「ユースケース記述」と「ルール・制約(=ドメイン知識)」を併用する設計の仕方はうちのチームにマッチしそうな気がします。 重厚なドキュメントになりすぎず、設計を議論できるものが記載されているのが良さそう。もっと詳細化が必要であればクラス図やシーケンス図として表現したり、そのままコードに落とし込んだりできそう。

モデルからどうコードに落とすか

形から入るの推奨。僕も以下を参考にしました。 github.com

  • 形から入る
    • 1ユースケースのお手本を用意しておく
    • イメージできてから横展開が楽
  • データモデルっぽいやつからリファクタリングしていく
    • ルールはどこに実装しているか
    • アプリケーション層にあるロジックをドメイン層に移す
  • コーディング ⇄ モデリング

QA

ブログに質問への回答を記載されております。 参考になります。

  • ORMはテーブルと一対一でない方がオススメ
  • モデリング時間は1時間くらい
    • 短いサイクルで繰り返す
  • 実践DDDに集約とトランザクションは切り離せないとある
  • 制約とかルールが明確なら値オブジェクト。無理に作る必要はない派
  • アプリケーション層の入り口でトランザクションはる
  • ユースケースでの記述とルール・制約は分ける
  • エンティティからリポジトリは使用しない方が良い(アプリケーション層からにした方がいいんではないかな)

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

安西 剛さん

インプット < アウトプット

参加者にアウトプットさせるようファシリテートをされていました。 隣の人と「なぜ今日来たか」「つらみの共有」「今後どうしたいか」などを短い時間(30秒程度)で共有しました。

DDDの広げ方

前半は経歴(つらみ)のリアルなお話があり、そこからタイトルの通り段階的に個人・仲間・組織へDDDを広めていくやり方について聞くことができました。 今の自分の課題は「本当に共感して仲間になってくれる人」を見つけてその人を中心にして「組織へ広げていく」ことと感じました。

  • 誰もやってない
    • 黙ってやる
    • プロダクトコードで練習
  • 自分はやっている
    • 仲間を選択する
      • 共感する人
      • 話せばわかる人
      • わからない人は巻き込まない
  • 複数人でやっている
    • 理解を広げる、深める
      • 勉強会
      • 上司を味方に
      • 有識者に教えを請う
  • チームでやっている
    • いきなり全体でなく、チームを広げる
      • チームをのれん分け
      • 失敗しても影響がないところから
      • 組織の2割を目指す
  • 大きな絵を描く(戦略を作る)
  • 整理整頓する
    • 分ける
    • 名前をつける
  • 世界地図からつくる
  • クラスを作る
  • やり方・あり方の両方を意識する
  • 戦略と実装を行ったり来たりする

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

www.slideshare.net

ほげさん

導入

  • 初学者に優しくない
  • フレーズに抵抗
  • 「君のドメイン層からは業務を感じない」

笑ってはいけないかと思うのですが、そのフレーズ最高でした。

試行錯誤

ほぼ独力で試行錯誤の軌跡がすごい。

印象に残ったアプローチが「インプット → メソッド名 → アウトプットを意地でも埋める(void消す)」というもの。 名詞=クラス、動詞=メソッド名とするのはロバストネス分析かな。この辺は一つのノウハウになりそうな感じ。

  • 名詞を探す
    • データの箱になる
  • ドメイン層に集める
    • テストが辛い
  • 動詞を探す(voidを消す)
    • イン → メソッド名 → アウト
    • 意地でも埋める
    • やっと絵がそれらしくなる(ここまでに2年から2年半くらいかかっている)
    • returnするクラスが必要だ

ブレイクスルーの先へ

  • ドメインか否かの境界」と「ドメインの中の境界」を探す
  • ドメイン境界を決める
    • 業務を変えてないのにドメイン層を変更してるのはおかしい
    • ドメインが知るドメインを減らす
    • 変わりやすい方に向かって線を引かない
      • 依存性逆転の原則
  • クラスとER図の関係
    • クラスの方が頻繁に変更される
    • データベースは変更されにくい

おまけと今後やりたいこと

  • テストコード不要論
  • エラー設計
    • ビジネスエラーとシステムエラーを分けたい
    • 本気で実行時例外をなくす

エラー設計については色々悩んだところであるのでぜひ最終結果を見てみたい。

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

かとじゅんさん

とにかく「値オブジェクトの設計に注力」「ドメインオブジェクトに凝集させる」のアプローチ

軽量DDDでつまづいた

この中で印象に残ったのは「ユビキタス言語にない実装都合の用語で作られたオブジェクト」です。 おるわーって思っていました。

あとはRDRAは積んでいるのでしっかり読めってことですね。

  • 通訳が必要になった
  • エンティティ=データ
  • トランザクションスクリプト亜種
  • ドメインモデル貧血症
  • ユビキタス言語にない実装都合の用語で作られたオブジェクト
  • RDRAで分析
  • 値オブジェクトに注力
  • 要件と行ったり来たり
  • 値オブジェクトで扱えた方が表現力あがる
  • ファーストコレクションで意図を表現する
  • スケーラブルな設計
    • ドメイン上の値はプリミティブでない
      • 値の範囲、ルール、計算能力を持つ
    • 値オブジェクトは不変にすること
      • 予測可能な設計を作り出せる

集約の境界定義に試行錯誤

  • 全部集約
    • ルールと振る舞いが分離
  • 集約を1つに
    • 説明が難しいモデル
      • 実装も大きくなる
      • I/Oコストも大きい

まとめ

  • PDR:Prep・Do・Review
  • 設計もFail Fast
  • コミュニティ活用

まとめ

  • 次やること
    • パッケージを意識する
    • ユースケース記述とドメイン知識(ルール・制約)の併記を試してみる
    • 「本当に共感して仲間になってくれる人」を見つけてその人を中心にして「組織へ広げていく」
    • RDRA読む
    • 「行ったり来たり」のサイクルを回す