DDD導入に踏み切れない方へ贈る「2層 + CQS アーキテクチャ(Flyweight DDD)」/Flyweight DDD

26e25726fc9da2f1e1f88c7be665407d?s=47 hiro@miraito
September 05, 2019

DDD導入に踏み切れない方へ贈る「2層 + CQS アーキテクチャ(Flyweight DDD)」/Flyweight DDD

Flyweight DDD
軽量DDDを避けつつ軽量(Flyweight)にDDDを導入するためのアーキテクチャです。

26e25726fc9da2f1e1f88c7be665407d?s=128

hiro@miraito

September 05, 2019
Tweet

Transcript

  1. DDD導入に踏み切れない方へ贈る 2層 + CQS アーキテクチャ (Flyweight DDD) 軽量DDDにならないための軽量なDDDのすゝめ

  2. 自己紹介 hiro@miraito PHPer 株式会社ミライトデザイン CEO 美容室サブスクリプションサービスMEZON 株式会社 Jocy CTO 好き

    : OOP, DDD, Architecture, Agile, Team Build 勉強会 : PHPer 向けワーキンググループぺちオブ主催 Object Oriented Conference主催 Twitter : @hirodragon112
  3. 今日話したいこと 1. このスライドのターゲット 2. DDD is 何 ? 3. 軽量DDDとは?

    4. 2層 + CQS アーキテクチャ
  4. 今日話したいこと 1. このスライドのターゲット 2. DDD is 何 ? 3. 軽量DDDとは?

    4. 2層 + CQS アーキテクチャ
  5. このスライドのターゲット このような方いませんでしょうか?

  6. このスライドのターゲット DDD良さそう。 DDD面白そう。 DDDに可能性を感じる。

  7. このスライドのターゲット でも、、、

  8. このスライドのターゲット いきなり導入する のはちょっと勇気 がいる・・・ もし途中でうまく いかなかったらど うしよう・・・

  9. このスライドのターゲット いつもどおりフ レームワークを ベースに開発す るか

  10. このスライドのターゲット (DDDは気になるんだけどね)

  11. このスライドのターゲット 今回はこんな方に提案したい アーキテクチャを紹介したいと思います。

  12. 2 + CQS Architecture (Flyweight DDD)

  13. このスライドのターゲット ・ Command … 書込み系。 副作用を持つ ・ Query … 参照系。返り値を返す

  14. 今日話したいこと 1. このスライドのターゲット 2. DDD is 何 ? 3. 軽量DDDとは?

    4. 2層 + CQS アーキテクチャ
  15. DDD is 何 ? Whatt’s DDD ??

  16. DDD is 何 ? 端的に言うと 「ドメインを中心に据えた設計」です。

  17. DDD is 何 ? 詳細は他の方がきっと語られていると思うので 本スライドでは割愛します。 (時間の都合上申し訳ないです)

  18. 今日話したいこと 1. このスライドのターゲット 2. DDD is 何 ? 3. 軽量DDDとは?

    4. 2層 + CQS アーキテクチャ
  19. 軽量DDDとは?

  20. 軽量DDDとは? 今回のテーマは 「軽量DDDにならないための軽量なDDD」 です。

  21. 軽量DDDとは? ・ そもそも軽量DDDとは? ・ あまり良くはないと言われる理由は?

  22. 軽量DDDとは? DDDは大きく分けて ・ 戦略的設計 ・ 戦術的設計 の2工程

  23. 軽量DDDとは? 戦略的設計 対象ドメインを理解し、システムに落とし込む為 の枠組み作り ユビキタス言語策定、ドメインモデリング(サブドメイン、境界コンテキスト) コンテキストマップ作成、等が戦略的設計に分類されます。

  24. 軽量DDDとは? 戦術的設計 具体的な実装パターン。 戦略設計により洗い出されたドメイン知識や ルールを具体的にコードに落とし込む為の手法 EntityやValue Object、Repository, Factory, 集約等々の実装パターンが戦術的設 計に分類されます。

  25. 軽量DDDとは? よく聞くDDDの説明 「対象ドメインをドメインエキスパートと共通の言 語となるユビキタス言語で語り、モデリングし、 そのモデリングがそのまま実装に落とし込まれ る」

  26. 軽量DDDとは? この説明は戦略的設計と戦術的設計が折り重 なって初めて実現できます。

  27. 軽量DDDとは? それでは軽量DDDと呼ばれるものはなんでしょ うか?

  28. 軽量DDDとは? それは、いわゆる戦術的設計のみを取り入れ た設計をさします。

  29. 軽量DDDとは? Aggregate root があり集約がEntityやValue Object により構成されていて Repository を使用 して永続化と再構築を行う・・・・というような、 DDDの戦術面(実装面)のみにフォーカスをあて

    た状態です。
  30. 軽量DDDとは? 軽量DDDの問題点は?

  31. 軽量DDDとは? 冒頭で触れましたがDDDとは 「ドメインを中心に据えた設計」 です

  32. 軽量DDDとは? あくまで中心に据えて守りたい(集中したい)コ アがあるからこそ(目的)、そしてそれらを具体 的な技術的関心事から分離する方法(手段)為 に、戦術的な設計が必要となります。

  33. 軽量DDDとは? つまり、ともすれば軽量DDDとは「目的」のない 「手段」となってしまう可能性があります。 だから軽量DDDにならないようにしましょうね、 みたいな事がよく言われているんですね。

  34. 今日話したいこと 1. このスライドのターゲット 2. DDD is 何 ? 3. 軽量DDDとは?

    4. 2層 + CQS アーキテクチャ
  35. 2層 + CQS アーキテクチャ ようやく本題にはいりますね。

  36. 2層 + CQS アーキテクチャ

  37. 2層 + CQS アーキテクチャ:概要 今日お話する内容は正攻法のDDDの話しではありません。 冒頭でも説明した通り、DDD導入を検討したいけど少し迷い がある。 という方に向けた少し亜流の手法を紹介したいと思います

  38. 2層 + CQS アーキテクチャ:概要 さらに具体的に言えば、部分的にでも良いから DDDを取り入れていく事で今後本格導入する為 の知見を得て行こう! というのが目的となります。

  39. 2層 + CQS アーキテクチャ:概要 ただし、、、

  40. 2層 + CQS アーキテクチャ:概要 「部分的に導入」と言っても軽量DDDはあんま 良くないんでしょ・・・?

  41. 2層 + CQS アーキテクチャ:概要 軽量DDDにならない為の軽量なDDD!!

  42. 2層 + CQS アーキテクチャ まず今から、今回立てた 「軽量DDDにならないための 2つの作戦」 を紹介します

  43. 2層 + CQS アーキテクチャ ① 戦略的設計をしっかりやる。 ② フレームワークの利点を可能な範囲で残す

  44. 2層 + CQS アーキテクチャ 一つずつ説明していきたいと思います

  45. 2層 + CQS アーキテクチャ:概要 軽量DDDにならないための作戦 ① 戦略的設計をしっかりやる。

  46. 2層 + CQS アーキテクチャ:概要 戦略設計を省略してはどうやっても軽量DDDに なってしまいます。 ここはもうつべこべ言わずやるしかないです。 やりましょう。やってみせましょう。やりとげま しょう!

  47. 2層 + CQS アーキテクチャ:概要 でもじゃあ、軽量化っていったいどこが軽量化 なの?

  48. 2層 + CQS アーキテクチャ:概要 戦術面を軽量化します!

  49. 2層 + CQS アーキテクチャ:概要 以上。

  50. 2層 + CQS アーキテクチャ:詳細

  51. 2層 + CQS アーキテクチャ:概要 軽量DDDにならないための作戦 ②

  52. 2層 + CQS アーキテクチャ:概要 普段PHPでシステム開発をしているのですが、 PHPerの中でも昨今DDDへの関心が非常に高 いと感じています。

  53. 2層 + CQS アーキテクチャ:概要 ただ、実際に導入してみた、チャレンジしてみた、 というプロダクトは増えているのか?というと肌 感としてはあまり増えていないように感じます。

  54. 2層 + CQS アーキテクチャ:概要 その背景に何があるかと言うと - フレームワークの便利さを捨てきれない - 慣れない手法を取る事へのリスクを感じる

  55. 2層 + CQS アーキテクチャ:概要 この2点が大きいのではと個人的には考えてい ます。

  56. 2層 + CQS アーキテクチャ:概要 軽量DDDにならないための作戦 ② フレームワークの利点を可能な限り残す

  57. 2層 + CQS アーキテクチャ:概要 これが亜流と書いた理由になります。 一般的にはFWに依存などあってはダメですよ ね。

  58. 2層 + CQS アーキテクチャ:概要 これは不慣れな手法にトライする際に余分な工 数が発生するので、慣れた手法を残す事で戦 略面にも時間を避けるようにしようというのが目 的です。

  59. 2層 + CQS アーキテクチャ:概要 また、PHPに限って言いますとLaravelでよく使用 されるORMのEloquentが非常に便利だから離 れられないという方もいますが、そういった方へ の解決の一つともなりえます。

  60. 2層 + CQS アーキテクチャ:概要 以上、2つの作戦を実現しつつDDDとしてのメ リットを守る一つのキーワードがあります。

  61. 2層 + CQS アーキテクチャ:概要 CQS

  62. 2層 + CQS アーキテクチャ:概要 CQSについては後ほど説明したいと思いますが、 まずは一般的なDDDのアーキテクチャを確認し たいと思います。

  63. None
  64. 2層 + CQS アーキテクチャ:概要 拡大した図です。 よくある UseCase(Application Service) がDomain層にあるEntityやDomain Serviceを操作して、最終的に

    Repositoryにより永続化、再構築を行 います。 よくある一般的な設計だと思います。 MVCのMはInfrastructure層、V, C は Presentation層にて使用されています。
  65. 2層 + CQS アーキテクチャ:概要 拡大した図です。 よくある UseCase(Application Service) がDomain層にあるEntityやDomain Serviceを操作して、最終的に

    Repositoryにより永続化、再構築を行 います。 よくある一般的な設計だと思います。 MVCのMはInfrastructure層、V, C は Presentation層にて使用されています。
  66. 2層 + CQS アーキテクチャ:概要 拡大した図です。 よくある UseCase(Application Service) がDomain層にあるEntityやDomain Serviceを操作して、最終的に

    Repositoryにより永続化、再構築を行 います。 よくある一般的な設計だと思います。 MVCのMはInfrastructure層、V, C は Presentation層にて使用されています。
  67. 2層 + CQS アーキテクチャ:概要 ここに先程立てた作戦を取り入れる事でDDDの 導入を試みつつもFWの利便性を残して開発に 余裕をもたせるのが今回の目的です。

  68. 2層 + CQS アーキテクチャ:概要 では、どのように作戦を取り入れるというか? ここで出てくるのが先程のCQSです。

  69. カウボーイの声 LB 「そう言えばCQSとCQRSって何が違うんだい?」 AJ 「そりゃまあRが違うんだろRが。きっと水だろうな」 LB 「なるほど。お前は相変わらず畑に水をまくんだな!」 CQSと近いCQRSという言葉も耳馴染みかと思います。 明確に定義された言葉を見つけられなかったのですが、CQRSはいわゆる「責務」 まで分離された状態を表します。

    また、「S」に関しても Separation と Segregation と言葉が違います。 詳細はおいておきますが、ここではデータモデルがCommandとQueryで完全に 独立しているかどうかを堺に言葉を使い分けています。(本当はもっと明確な違 いがあると思いますが)
  70. 2層 + CQS アーキテクチャ:概要 CQS(Command Query Separation) とは 端的に言うとCommand(書き込み処理)と Query(読み込み処理)を分離して扱おう

    という手法です。
  71. 2層 + CQS アーキテクチャ:概要 今回はこの考え方を取り入れて、立てた作戦を 実行したいと思います。 どういうことかと言うと、、、

  72. 2層 + CQS アーキテクチャ:概要 CQSによりCommandとQueryを分割した上で 「Command部分は戦術的設計を導入」し、 「Query部分はFWに依存した設計」にしてしまお う という作戦です。

  73. 2層 + CQS アーキテクチャ:概要 それでは具体的にCommandとQuery用のそれ ぞれのアーキテクチャを見ていきたいと思いま す。

  74. Command時 基本的に通常のDDDと変 わらない。 Command操作は副作用を 伴いシステムの状態を変 更する。 DDDの集約設計などドメイ ン固有のルールやロジック を中心に据えた設計にて しっかりと対象ドメインの活

    動をシステムに落とし込む。 トランザクション管理もこち らのみ
  75. 具体的に見るとわかります が、Command時は一般的 なアーキテクチャを採用し ます。 DDDをやる以上、Domain の知識を明確に分離して 対象を意図的に表現する 必要があります。 集約によるライフサイクル の管理やValue

    Object に よって値の表現を的確に 行います。
  76. Query時 今回の作戦のミソとなる。 参照系の操作を分離し、こ こに関してはがっつりとFW に依存した設計とする。 副作用を伴わない参照系 操作に限定する事によりド メインルールを壊す心配が ない。 また、FWのORMの便利機

    能等をそのまま使用でき 開発スピードも極限まで落 とさずに済む。 例えば参照したModelをそ のままViewに渡して使用 するとかも問題ない。
  77. Query時 いわゆる参照系の際は非 常にシンプルです。 Repository によるDomain Object の再構築もしませ ん。 DBを直接ORMを使用して 参照します。

    この辺はDDD導入以前の 普段どおりの開発が行な えます。
  78. Query時 また、Presenter が直接 ORMのModelを使用してい ます。 画面の描画用にこのまま Viewに渡してしまっても良 いです。 Pagenator 等

    ORMの便利 機能をそのままViewでも 使ってしまいましょう。 もうViewModelに詰め変え る日々も、ValueObjectをUI で使用して良いかも悩む 必要はありません。 FWサイコー
  79. 2層 + CQS アーキテクチャ:概要 メリット Repository肥大化など導入時にありがちな問題を防げる 完全導入によりも導入コストを抑える事ができ、本来重要な戦略的設計に工数 をかけられる 最悪Command側を直せばいつもの開発に戻れる。

  80. 2層 + CQS アーキテクチャ:概要 デメリット DDDとFWどちらも中途半端になる 当然ながら参照処理には依存が発生しまくる DB直接依存なので参照系の単体テストが書き辛くなる 参照もドメイン知識な場合適用できない

  81. まとめ 今回紹介した 「Flyweight DDD 」 は、あくまで亜流、かつ最適解とはならないため もし参考にされる際は自己責任でお願いいたします。 また、知見がまだまだ足りていない為試しながらフィードバックを受けながら 改善していきたいと思います。

  82. まとめ YYPHPにてフルバージョンを発表した所 わかりやすい名前があると良いかもという事で @suin さんに命名して頂いたのでこのアーキテクチャを FWDDD (Flyweight DDD) と命名したいと思います。