Save 37% off PRO during our Black Friday Sale! »

混沌からドメインモデルへ

 混沌からドメインモデルへ

カオスな実装のプロジェクトにおいて
カオス → Fat Model
Fat Model → ドメインモデル
と段階を経て、リファクタリングに取り組んだ試み

B8403d102456248570005ee7fb2ba0f7?s=128

philomagi

July 30, 2019
Tweet

Transcript

  1. 混沌からドメインモデルへ 段階的リファクタリングの試み 2019/07/30@設計会議

  2. 発表者 topo / @Philomagi • 主にフロントエンド主体のWEB系エンジニア • ScalaとTypescriptとRubyが好き ◦ Rubyは最近、公私共に若干疎遠

    • PHPは中々縁が切れない悪友 ◦ 最近は、そう腐すほどでもないかなと思い始めてる
  3. 概要 • 設計が存在しないプロジェクト • 既存コードが色々とアレ • まずはFat Modelで手元を見えるように • 道具を揃えてからドメインモデルへ

  4. 1. 混沌

  5. 混沌とした状況 • コードの重複 • モデル貧血症 • 詳細に依存 • UtilityじゃないUtil

  6. カプセル化?なにそれ美味しいの? $props = Hash::extract($item->get('props'), "{n}[name=/^{$propName}[.]/]" ※Viewのコード(イメージ)

  7. カプセル化?なにそれ美味しいの? return [ 'stock.enough' => $item->get('stock.amount') >= 10, // 中略

    'status.hoge' => count($item->extract("props.{n}[name={$hogeStatusName}]")) >= 1, ]; ※Utilのコード(イメージ)
  8. View Controller Util Model Hash

  9. View Controller Util Model Hash • Fat View(Smart UI) •

    Fat Controller • Fat Util • 貧血モデル
  10. 2. 混沌からFat Modelへ

  11. Why Fat Model? • 次々に飛んでくる回収要望・追加機能 ◦ モデル分析のための時間も体力も確保し難い • 取り敢えず、直近触るコードだけでも見通しよくした い

  12. Fat Modelへ • ロジックをDTOへ集約 • 詳細へのアクセスをメソッド経由に • 必要に応じてValueObjectも追加 • Utilは基本的に削除

    ◦ 入り組んでるものは、可能ならModel経由の利用に変更
  13. Before / After $props = Hash::extract($item->get('props'), "{n}[name=/^{$propName}[.]/]" $sizes = $item->getSizesWhere($sizeName);

  14. Before / After return [ 'stock.enough' => $item->get('stock.amount') >= 10,

    // 中略 'status.hoge' => count($item->extract("props.{n}[name={$hogeStatus}]")) >= 1, ]; return [ 'stock.enough' => $item>stock()->isEnough(), // 中略 'status.hoge' => $item>isHoge(), ];
  15. View Controller Util Model Hash

  16. View Controller Util Model Hash • Fat Model

  17. 3. Fat Model から Domain Model へ

  18. • モデルを描いて共有 ◦ 仕様を握っている人と認識を揃える • 語彙を統一 ◦ DDDにおけるユビキタス言語 • 部分的に、使えるところから導入開始

    ◦ 一気の置き換えは狙わない Domain Model の導入
  19. Domain Object の実装 • 統一した語彙を、クラス名/メソッド名で使用する • データとDomain Objectの分離 ◦ DTO

    → Domain Objectのマッピング層を用意 ◦ Factory、Repository • Modelに集約したロジックをDomain Objectに移動 ◦ ModelはただのDTOになり、ロジックはDomain Objectが持つ • パッケージでコンテクストを表現 ◦ パッケージ内のオブジェクトは、ひたすらそのコンテクストに特化
  20. View Controller DomainObject DomainObject View Controller DomainObject View Controller Mapping

    Infrastructure Model(DTO) Mapping Mapping
  21. 振り返って プラマイ両方有ったが、マイナスが強い • 「何が用意してあるのか」「何が用意されてないのか」を確認 できる • 「とりあえず読めなくはない」には持っていける • Modelに強く依存した実装になってしまう ◦

    DTOがプロジェクト全体を支配してしまうため
  22. 評価 • 今回はとにかくスタート地点が真っ暗闇だった • まずは手元に何が有り、何が無いのかを把握したかった • 今回のケースでは、一定程度の妥当性は有ったかなと感じて いる • 決して、Bestなプロセスでは無いと思う

    ◦ 緊急回避的 ◦ 経由せずに済むなら経由しない方が良い
  23. 反省点 • 「設計しない」ための言い訳としてFat Model化し た感も有る • 設計を後回しにしたことで首が締まったことも多い • 複雑なシステムこそ、時間が無くともきちんと設計 すべき

  24. ご清聴ありがとうございました