Flyweight DDD 軽量DDDを避けつつ軽量(Flyweight)にDDDを導入するためのアーキテクチャです。
DDD導入に踏み切れない方へ贈る2層 + CQS アーキテクチャ (Flyweight DDD)軽量DDDにならないための軽量なDDDのすゝめ
View Slide
自己紹介hiro@miraitoPHPer株式会社ミライトデザイン CEO美容室サブスクリプションサービスMEZON株式会社 Jocy CTO好き :OOP, DDD, Architecture, Agile, Team Build勉強会 :PHPer 向けワーキンググループぺちオブ主催Object Oriented Conference主催Twitter :@hirodragon112
今日話したいこと1. このスライドのターゲット2. DDD is 何 ?3. 軽量DDDとは?4. 2層 + CQS アーキテクチャ
このスライドのターゲットこのような方いませんでしょうか?
このスライドのターゲットDDD良さそう。DDD面白そう。DDDに可能性を感じる。
このスライドのターゲットでも、、、
このスライドのターゲットいきなり導入するのはちょっと勇気がいる・・・もし途中でうまくいかなかったらどうしよう・・・
このスライドのターゲットいつもどおりフレームワークをベースに開発するか
このスライドのターゲット(DDDは気になるんだけどね)
このスライドのターゲット今回はこんな方に提案したいアーキテクチャを紹介したいと思います。
2 + CQSArchitecture(Flyweight DDD)
このスライドのターゲット・ Command … 書込み系。 副作用を持つ・ Query … 参照系。返り値を返す
DDD is 何 ?Whatt’s DDD ??
DDD is 何 ?端的に言うと「ドメインを中心に据えた設計」です。
DDD is 何 ?詳細は他の方がきっと語られていると思うので本スライドでは割愛します。(時間の都合上申し訳ないです)
軽量DDDとは?
軽量DDDとは?今回のテーマは「軽量DDDにならないための軽量なDDD」です。
軽量DDDとは?・ そもそも軽量DDDとは?・ あまり良くはないと言われる理由は?
軽量DDDとは?DDDは大きく分けて・ 戦略的設計・ 戦術的設計の2工程
軽量DDDとは?戦略的設計対象ドメインを理解し、システムに落とし込む為の枠組み作りユビキタス言語策定、ドメインモデリング(サブドメイン、境界コンテキスト)コンテキストマップ作成、等が戦略的設計に分類されます。
軽量DDDとは?戦術的設計具体的な実装パターン。戦略設計により洗い出されたドメイン知識やルールを具体的にコードに落とし込む為の手法EntityやValue Object、Repository, Factory, 集約等々の実装パターンが戦術的設計に分類されます。
軽量DDDとは?よく聞くDDDの説明「対象ドメインをドメインエキスパートと共通の言語となるユビキタス言語で語り、モデリングし、そのモデリングがそのまま実装に落とし込まれる」
軽量DDDとは?この説明は戦略的設計と戦術的設計が折り重なって初めて実現できます。
軽量DDDとは?それでは軽量DDDと呼ばれるものはなんでしょうか?
軽量DDDとは?それは、いわゆる戦術的設計のみを取り入れた設計をさします。
軽量DDDとは?Aggregate root があり集約がEntityやValueObject により構成されていて Repository を使用して永続化と再構築を行う・・・・というような、DDDの戦術面(実装面)のみにフォーカスをあてた状態です。
軽量DDDとは?軽量DDDの問題点は?
軽量DDDとは?冒頭で触れましたがDDDとは「ドメインを中心に据えた設計」です
軽量DDDとは?あくまで中心に据えて守りたい(集中したい)コアがあるからこそ(目的)、そしてそれらを具体的な技術的関心事から分離する方法(手段)為に、戦術的な設計が必要となります。
軽量DDDとは?つまり、ともすれば軽量DDDとは「目的」のない「手段」となってしまう可能性があります。だから軽量DDDにならないようにしましょうね、みたいな事がよく言われているんですね。
2層 + CQS アーキテクチャようやく本題にはいりますね。
2層 + CQS アーキテクチャ
2層 + CQS アーキテクチャ:概要今日お話する内容は正攻法のDDDの話しではありません。冒頭でも説明した通り、DDD導入を検討したいけど少し迷いがある。という方に向けた少し亜流の手法を紹介したいと思います
2層 + CQS アーキテクチャ:概要さらに具体的に言えば、部分的にでも良いからDDDを取り入れていく事で今後本格導入する為の知見を得て行こう!というのが目的となります。
2層 + CQS アーキテクチャ:概要ただし、、、
2層 + CQS アーキテクチャ:概要「部分的に導入」と言っても軽量DDDはあんま良くないんでしょ・・・?
2層 + CQS アーキテクチャ:概要軽量DDDにならない為の軽量なDDD!!
2層 + CQS アーキテクチャまず今から、今回立てた「軽量DDDにならないための 2つの作戦」を紹介します
2層 + CQS アーキテクチャ① 戦略的設計をしっかりやる。② フレームワークの利点を可能な範囲で残す
2層 + CQS アーキテクチャ一つずつ説明していきたいと思います
2層 + CQS アーキテクチャ:概要軽量DDDにならないための作戦 ①戦略的設計をしっかりやる。
2層 + CQS アーキテクチャ:概要戦略設計を省略してはどうやっても軽量DDDになってしまいます。ここはもうつべこべ言わずやるしかないです。やりましょう。やってみせましょう。やりとげましょう!
2層 + CQS アーキテクチャ:概要でもじゃあ、軽量化っていったいどこが軽量化なの?
2層 + CQS アーキテクチャ:概要戦術面を軽量化します!
2層 + CQS アーキテクチャ:概要以上。
2層 + CQS アーキテクチャ:詳細
2層 + CQS アーキテクチャ:概要軽量DDDにならないための作戦 ②
2層 + CQS アーキテクチャ:概要普段PHPでシステム開発をしているのですが、PHPerの中でも昨今DDDへの関心が非常に高いと感じています。
2層 + CQS アーキテクチャ:概要ただ、実際に導入してみた、チャレンジしてみた、というプロダクトは増えているのか?というと肌感としてはあまり増えていないように感じます。
2層 + CQS アーキテクチャ:概要その背景に何があるかと言うと- フレームワークの便利さを捨てきれない- 慣れない手法を取る事へのリスクを感じる
2層 + CQS アーキテクチャ:概要この2点が大きいのではと個人的には考えています。
2層 + CQS アーキテクチャ:概要軽量DDDにならないための作戦 ②フレームワークの利点を可能な限り残す
2層 + CQS アーキテクチャ:概要これが亜流と書いた理由になります。一般的にはFWに依存などあってはダメですよね。
2層 + CQS アーキテクチャ:概要これは不慣れな手法にトライする際に余分な工数が発生するので、慣れた手法を残す事で戦略面にも時間を避けるようにしようというのが目的です。
2層 + CQS アーキテクチャ:概要また、PHPに限って言いますとLaravelでよく使用されるORMのEloquentが非常に便利だから離れられないという方もいますが、そういった方への解決の一つともなりえます。
2層 + CQS アーキテクチャ:概要以上、2つの作戦を実現しつつDDDとしてのメリットを守る一つのキーワードがあります。
2層 + CQS アーキテクチャ:概要CQS
2層 + CQS アーキテクチャ:概要CQSについては後ほど説明したいと思いますが、まずは一般的なDDDのアーキテクチャを確認したいと思います。
2層 + CQS アーキテクチャ:概要拡大した図です。よくある UseCase(Application Service)がDomain層にあるEntityやDomainServiceを操作して、最終的にRepositoryにより永続化、再構築を行います。よくある一般的な設計だと思います。MVCのMはInfrastructure層、V, C はPresentation層にて使用されています。
2層 + CQS アーキテクチャ:概要ここに先程立てた作戦を取り入れる事でDDDの導入を試みつつもFWの利便性を残して開発に余裕をもたせるのが今回の目的です。
2層 + CQS アーキテクチャ:概要では、どのように作戦を取り入れるというか?ここで出てくるのが先程のCQSです。
カウボーイの声LB 「そう言えばCQSとCQRSって何が違うんだい?」AJ 「そりゃまあRが違うんだろRが。きっと水だろうな」LB 「なるほど。お前は相変わらず畑に水をまくんだな!」CQSと近いCQRSという言葉も耳馴染みかと思います。明確に定義された言葉を見つけられなかったのですが、CQRSはいわゆる「責務」まで分離された状態を表します。また、「S」に関しても Separation と Segregation と言葉が違います。詳細はおいておきますが、ここではデータモデルがCommandとQueryで完全に独立しているかどうかを堺に言葉を使い分けています。(本当はもっと明確な違いがあると思いますが)
2層 + CQS アーキテクチャ:概要CQS(Command Query Separation)とは 端的に言うとCommand(書き込み処理)とQuery(読み込み処理)を分離して扱おうという手法です。
2層 + CQS アーキテクチャ:概要今回はこの考え方を取り入れて、立てた作戦を実行したいと思います。どういうことかと言うと、、、
2層 + CQS アーキテクチャ:概要CQSによりCommandとQueryを分割した上で「Command部分は戦術的設計を導入」し、「Query部分はFWに依存した設計」にしてしまおうという作戦です。
2層 + CQS アーキテクチャ:概要それでは具体的にCommandとQuery用のそれぞれのアーキテクチャを見ていきたいと思います。
Command時基本的に通常のDDDと変わらない。Command操作は副作用を伴いシステムの状態を変更する。DDDの集約設計などドメイン固有のルールやロジックを中心に据えた設計にてしっかりと対象ドメインの活動をシステムに落とし込む。トランザクション管理もこちらのみ
具体的に見るとわかりますが、Command時は一般的なアーキテクチャを採用します。DDDをやる以上、Domainの知識を明確に分離して対象を意図的に表現する必要があります。集約によるライフサイクルの管理やValue Object によって値の表現を的確に行います。
Query時今回の作戦のミソとなる。参照系の操作を分離し、ここに関してはがっつりとFWに依存した設計とする。副作用を伴わない参照系操作に限定する事によりドメインルールを壊す心配がない。また、FWのORMの便利機能等をそのまま使用でき開発スピードも極限まで落とさずに済む。例えば参照したModelをそのままViewに渡して使用するとかも問題ない。
Query時いわゆる参照系の際は非常にシンプルです。Repository によるDomainObject の再構築もしません。DBを直接ORMを使用して参照します。この辺はDDD導入以前の普段どおりの開発が行なえます。
Query時また、Presenter が直接ORMのModelを使用しています。画面の描画用にこのままViewに渡してしまっても良いです。Pagenator 等 ORMの便利機能をそのままViewでも使ってしまいましょう。もうViewModelに詰め変える日々も、ValueObjectをUIで使用して良いかも悩む必要はありません。FWサイコー
2層 + CQS アーキテクチャ:概要メリットRepository肥大化など導入時にありがちな問題を防げる完全導入によりも導入コストを抑える事ができ、本来重要な戦略的設計に工数をかけられる最悪Command側を直せばいつもの開発に戻れる。
2層 + CQS アーキテクチャ:概要デメリットDDDとFWどちらも中途半端になる当然ながら参照処理には依存が発生しまくるDB直接依存なので参照系の単体テストが書き辛くなる参照もドメイン知識な場合適用できない
まとめ今回紹介した「Flyweight DDD 」は、あくまで亜流、かつ最適解とはならないためもし参考にされる際は自己責任でお願いいたします。また、知見がまだまだ足りていない為試しながらフィードバックを受けながら改善していきたいと思います。
まとめYYPHPにてフルバージョンを発表した所わかりやすい名前があると良いかもという事で@suin さんに命名して頂いたのでこのアーキテクチャをFWDDD (Flyweight DDD) と命名したいと思います。