Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Railsで考えるドメイン駆動設計のコアドメイン
Search
MinoDriven
October 23, 2020
Programming
49
14k
Railsで考えるドメイン駆動設計のコアドメイン
銀座Rails#26の登壇資料です
https://ginza-rails.connpass.com/event/189892/
MinoDriven
October 23, 2020
Tweet
Share
More Decks by MinoDriven
See All by MinoDriven
破壊せよ!データ破壊駆動で考えるドメインモデリング / data-destroy-driven
minodriven
18
4.4k
アーキテクチャレベルで考える開発生産性 / architecture-and-productivity
minodriven
22
11k
見えないものに着目すると上手くいく、モデリングの勘所 / invisible-driven-design
minodriven
22
6.6k
クソコード動画『カプセル化 Mk-II』 で考える 上手くカプセル化できない理由 / encapsulation2
minodriven
21
16k
技術的負債の怨霊と除霊方法 / ghosts-of-technical-debt
minodriven
11
4.2k
分岐を低減するinterface設計と発想の転換 / interface_design_idea.pdf
minodriven
17
6.6k
目的と抽象化の関係性から分かる、システムの設計精度を高める考え方 / purpose abstraction design
minodriven
22
8.8k
『良いコード/悪いコードで学ぶ設計入門』を一歩深める読み方 / deepen good code bad code
minodriven
18
6.9k
風刺動画「一枚岩モデル」で考える、DDDの境界付けられたコンテキスト / huge model vs bc
minodriven
19
39k
Other Decks in Programming
See All in Programming
Figma Dev Modeで変わる!Flutterの開発体験
watanave
0
150
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
cmp.Or に感動した
otakakot
3
210
みんなでプロポーザルを書いてみた
yuriko1211
0
280
Click-free releases & the making of a CLI app
oheyadam
2
120
ローコードSaaSのUXを向上させるためのTypeScript
taro28
1
630
アジャイルを支えるテストアーキテクチャ設計/Test Architecting for Agile
goyoki
9
3.3k
as(型アサーション)を書く前にできること
marokanatani
10
2.7k
Arm移行タイムアタック
qnighy
0
340
React への依存を最小にするフロントエンド設計
takonda
7
1.6k
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
Tauriでネイティブアプリを作りたい
tsucchinoko
0
370
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
520
39k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
44
2.2k
A Philosophy of Restraint
colly
203
16k
What's new in Ruby 2.0
geeforr
343
31k
Side Projects
sachag
452
42k
Optimising Largest Contentful Paint
csswizardry
33
2.9k
Facilitating Awesome Meetings
lara
50
6.1k
Typedesign – Prime Four
hannesfritz
40
2.4k
The Pragmatic Product Professional
lauravandoore
31
6.3k
The Art of Programming - Codeland 2020
erikaheidi
52
13k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
Building Applications with DynamoDB
mza
90
6.1k
Transcript
Railsで考える ドメイン駆動設計の コアドメイン 2020/10/23(金) 銀座Rails#26 ミノ駆動 (@MinoDriven)
アジェンダ • 自己紹介 • 本スピーチの目的 • ドメイン駆動設計の「ドメイン」とは • コアドメインとは •
コアドメインの価値向上手法 • DDD実現手段とRailsへの応用、その考え方 • 巨大Railsレガシーの技術的負債にDDDで立ち向かった例 • DDD向き不向き • まとめ
自己紹介 • ミノ駆動(@MinoDriven) • リファクタリング大好き。 • クソコードを滅ぼす技術が大好き。 • たまに夢の中でもリファクタリング… •
㈱クラウドワークスではリファクタリングや設計が主任 務。 • 巨大Railsレガシーの技術的負債に対し、DDDベースに リファクタリング実践中。
職歴 1社目 ㈱NECネットワーク・センサ:ファームウェア、電子回路 設計 2社目 キヤノン㈱:医療X線撮像ソフトウェア、工場監視用画 像処理サーバの開発、リファクタリング 3社目現職 ㈱クラウドワークス:「自社のRailsレガシーがヤバ いのでリファクタリングしてほしい」とTwitter上でナンパされ入 社 • C#を十数年、その他CやC++で組み込みやWindowsネイ
ティブの開発経験が長いです。 • Web系はまだ1年半ほど。Rails含めてWeb周辺技術は 全然浅いです。
Qiita
クソコード動画
バグ退治RPG「バグハンター2 Reboot」制作中
ドメイン駆動設計とは エリック・エヴァンス氏が考案した設計手法。 ドメインモデルのモデリングを中心に、ソフトウェア 開発に伴う複雑さを解決する。 長期的な開発力向上に威力を発揮すると言われて いる。 特にマイクロサービス化ではほぼほぼセットで語ら れる。
ドメイン駆動設計に対するイメージ なんだか 難しそう… 設計パターン集? Railsでは 無理 アカデミックな理論で 実用性なし 机上の空論
RailsではDDDは難しい? お互いの良さを 殺してしまう Rails-wayから 外れてしまう DDDやりたいなら はじめから Rails使うな 型がなくて つらい
ちょっと待て コアドメインはどこに行った
コアドメインが語られない違和感 DDDを採用するかどうかとか、RailsでDDDは困難とか議論する 以前に、そもそもDDDのコアドメインが議論されているのをあまり 見聞きしたことがない。 DDDではコアドメインが真の主人公なのに!!
軸がなくフワフワと漂う議論 何のためにDDDで設計するか、その議論はコアドメインを意識す ることが必須。 しかしコアドメインがすっぽ抜けているために、DDDは「設計パ ターン集なんでしょ」とか「アーキテクチャが合わないから無理」と か(私から見ると)いまいち議論の軸が定まっていないように見え る。
目的 そこで本日はDDDの真の主人公コアドメインを中心に、ドメイン駆 動設計で解決したいことの理解を目的とします。 その上で、RailsとDDDとの関係や、どう応用するかについて考え るキッカケを皆様にご提供することを目的とします。
まずはRailsから離れて ソフトウェア開発全般の事柄として 聞いて下さい。 (※あとでRailsの話をします)
DDD序文 DDD序文より引用。いの一番でコアドメインが登場している。 「境界付けられたコンテキスト」や「ユビキタス言語」は頻繁に議論されるが、どういうわ けかコアドメインだけが空気扱い。
「コアドメイン」って何よ? …の前に、 ドメイン駆動設計の 「ドメイン」とは。
ドメイン(問題領域): RPGを楽しみたい 解決領域: ドラゴンクエスト 解決領域: ファイナルファンタジー メラ メラミ ファイア メラ
ゾーマ ファイラ ファイガ ドメインモデル: ActiveRecordではない。 ドメインの課題を解決するモデルであり、物事の特定の側面を抽象化したもの。 ドメイン課題を効果的に解決するための 変換能力を備えた概念。変換能力がなければド メインモデルとは呼べない。
問題領域: RPGを楽しみたい 様々な戦い方、成長を 楽しみたい アイテムコンプ したい 魔法で 戦いたい 解決領域: ドラゴンクエスト
武闘家 バイ キルト 小さな メダル 盗賊 賢者 ニフラム メド ローア ドメインには、さらに個々のドメイン(問題領域)がある。 各問題領域の解決に貢献するドメインモデルがいる。
問題領域: SNSを楽しみたい 情報収集 話題性 コンテンツ 健全性 解決領域: Twitter ブック マーク
ミュート リツイート モーメント リスト ブロック 通報 Twitterの例 いいね フォロー
皆さんそれぞれが 開発しているサービスの ドメインやドメインモデルを 考えてみましょう。 個々の問題領域を 思い浮かべましょう。
イメージできました?
…と、 ここでいきなり経営者視点
どこに開発リソースを投じるか? 開発リソースは有限です。 限られた予算、時間、人材の中で、開発に投資しなければいけま せん。 サービスには対象とする問題領域が様々あります。 どこの問題領域に投資すれば顧客の課題を解決し、顧客に訴求 し、大きく利益を得られるでしょうか?
どこが費用対効果が高い? あのニーズ? それとも別の顧客課題?
あなたのサービスの ウリは何ですか?
それこそが コアドメイン
コアドメインとは システム内で最大の価値を付加すべき場所。 価値があり重要で、費用対効果が最大の箇所。 競争優位性があり、差別化が図られ、ビジネス上優位に立つポイント。 優位に立つため設計の一部を秘密にしておく場合もある。 コアドメインの名の通り、ビジネスの中心的な問題領域。 問題領域 コアドメイン 汎用 サブドメイン
支援 サブドメイン
自分たちのサービスがいまいち顧客に訴求しない …。折角開発したのに顧客にウケない…。利益が上 がらない。 自分たちのサービスのウリは分かっている。もっとウ ケるように次々新しい仕様を盛り込みたい。でもウリ の部分がクソコードすぎて、スピーディーに開発でき ない…。開発コストだけがいたずらに増大する。 こんな課題を解決するのがドメイン駆動設計。
ドメイン駆動設計の目的 ドメイン駆動設計は、コアドメインについて、以下2点の継続的な向 上を目指し、サービスを継続的に利益体質にする設計思想である。 ビジネス価値:コアドメインのビジネス価値を向上し、顧客に訴求し (つまりバカウケし)、サービス利益の最大化を図る。 開発生産性:コアドメインを構成するモジュールの変更容易性を高 め、低コストでスピーディーにコアドメインの価値を向上する。
有名サービスの コアドメインは何かを 考えてみる ※登壇者の私見、解釈であり、 実際とは違う可能性が多分にあります
Twitter のコアドメインは?
問題領域: SNSを楽しみたい 情報収集 話題性 コンテンツ 健全性 解決領域: Twitter ブック マーク
ミュート リツイート モーメント リスト ブロック 通報 いいね フォロー 話題性に貢献する、他にはない 非常に特徴的なモデル おそらく コアドメイン
リングフィットアドベンチャー のコアドメインは?
問題領域: フィットネスゲームを楽しみたい 飽きずに 続けたい 解決領域: リングフィットアドベンチャー リング君 フィット スキル ステージ
ギミック プレイヤーの運動動作を モンスターへの攻撃に変換する 非常に画期的なモデル おそらくコアドメイン (開発者インタビューの内容より ) アドバイザであり、 心理的にサポートするメンター 道中の様々なギミックの正 体は、動的なフィットネスメ ニュー。
なぜコアドメインとそれ以外を区別するか 開発リソースが有限だから。費用対効果を最大化したいから。 サービスが巨大化してくると、サービスの中心的な価値が何であるか、だんだん分から なくなってくる。 費用対効果を高め、差別化を図って競争優位性を得るには、何が自分たちの中心的価 値かを理解するのが肝要。サブ的要素や的外れな要素に投資してもリターンは薄い。 著者エヴァンス氏「手の込んだ設計を、あらゆる詳細への適用を推奨しているわけでは ない。重要な箇所に集中する」(意訳「全部DDDでやれとは言ってない」
エヴァンスさんが考案した コアドメイン価値向上の手法
①ビジネス価値向上に関連する手法(一部抜粋) 手法 説明 ドメインエキスパート 問題領域に関して深い知識を持つメンバー。 ドメインビジョン声明文 コアドメインの価値を簡潔に説明した文書。 深いモデル コアドメインの本質的課題の解決に大きく貢献する、重要モデル。 暗黙的概念
本質理解に重要だが、明示的に示されない隠れた概念。 ユビキタス言語 ビジネス概念を噛み砕き、ソフトウェアが解決したい本質的概念を理解する ための言語。 顧客のニーズに訴求し利益を増大するには、顧客課題の本質を理解し、 その本質的課題を解決するドメインモデルを発見・発明・改良しなければ ならない。 フィット スキル リツイート コアドメインと同様にドメインモデルの価値向上も DDDの議論であまり語られない!でも超重要!!
②開発生産性向上に関連する手法(一部抜粋) 手法 説明 ユビキタス言語 関係者全員の意思疎通の精度とコストパフォーマンス向上に貢献。 ドメイン層 UIやDBなど他の技術レイヤから隔離され、問題領域の課題解決に貢献す るピュアな層。コアドメインの構成要素を他から隔離する。 Repository 永続化ロジックをドメインロジックから隔離する設計パターン。
ValueObject 値の振る舞いを表現する、 DDDで基本にして重要なパターン。 コアドメインを解決するロジックが低凝集密結合なクソコードになっていると、折角ビジネ スチャンスがあってもすぐに変更できず、市場要求に素早く対応できなくなる。また、コア ドメインに貢献する概念(ドメインモデル)に相当するロジックを発見したり、改良するの が困難になる(やりたいことはむしろコレ)。 だから以下各種設計手法を用い、コアドメインのロジックをクリーンな構造にして開発生 産性を向上させなければならない。
ここで唐突に質問です
世の中には様々なサービスがあります。 どのサービスにも、それぞれウリになる部分があります。 つまり、コアドメインが存在します。
でもどのサービスがRails製で、どのサービスが非 Rails製か、パッと見で見分けがつきますか?
JavaだからSpringBootだからコアドメインがある、 Railsだからコアドメインがない、ではないはず。それ らは実装方法の違いに過ぎません。 ゆえにRailsアプリにも、対象とするコアドメインがあ ります。
サービスのウリになる部分を 把握していますか?
ウリの部分の設計は クリーンですか? 高い開発生産性を出せる、 変更コストが低い設計に なっていますか?
View Controller ActiveRecord ActiveRecord ActiveRecord :重要ビジネスロジック 重要ビジネスロジックがあちこち に散在している。 そのため、サービスの中心的価 値が何なのか、ロジックレベルで
認識困難な状態。 関係し合う重要ロジックや影響 範囲を探し回らないといけない ため、高い開発生産性を出せな い。
View Controller ActiveRecord Domain ActiveRecord ActiveRecord :重要ビジネスロジック 重要ビジネスロジックをドメイン 層に凝集。他の関心事(例え ばUI制御やDB制御)から隔離
する。 サービスの中心的価値を認識 しやすくなる。 関係し合う重要ロジックがドメ イン層内で整理されていること で高い開発生産性を出せる。 注文 予約 割引金額 クリスマス キャンペーン 特別会員価格
View Controller ActiveRecord ActiveRecord :重要ビジネスロジック Rails新規開発では始めから何をウ リにするか狙いを立ててるから、そ もそもコアドメインを喪失していな い。 コアドメインを解決する重要ロジック
が散らばっていることもないから、 DDDでやる価値が薄い。 そもそもRails-wayに乗る利点が薄 れてしまう。
DDD実現手段に関するエヴァンス氏の見解 DDDはコアドメインの価値を高めるため、コアドメインを構成 するロジックをドメイン層へ隔離し、ドメインモデルをドメインオ ブジェクトとして設計実装するのを実現の主眼としている。 実現手段は、オブジェクト指向言語がやりやすい、と言ってる だけで、それ以外じゃダメだとは言ってない。手続き型言語で も限定的には可能。 DDDに登場するパターン以外にも、GoFのデザインパターン で使えるものが様々あり、活用できることは素晴らしい、と述 べている。
DDD実現手段を巡る解釈 Aggregate、ValueObjectなど、DDDで紹介されているパターンは、「こうすればDDDを 実現しやすい」とエヴァンス氏が考案した手段のひとつに過ぎない。 先の手続き型言語やGoFに対する見解も加味すると、Rails流のDDD実現手段が編み 出されてもいいのでは?と考える。
エヴァンス氏に関係なく我々がどう設計するか エヴァンス氏はエンジニアの一人であり、何が何でも彼の設計方針通り全て従わなけれ ばならない理由はない。 設計界隈では、DDDに関してより実用的に改善する動きがある。例えばユースケース 層を設けたり(※1)、「ドメインじゃ分かりにくいから『人の営み』と呼称しよう(※2)」など。 ※1:松岡幸一郎氏( @little_hand_s )「ドメイン駆動設計 モデリング/実装ガイド」( https://booth.pm/ja/items/1835632
) ※2:林宏勝氏( @hirodragon112 )「概念投影によるオブジェクト指向設計の考え方とその方法」 ( https://speakerdeck.com/hirodragon112/conceptual-projection-design )
エヴァンス氏に関係なく我々がどう設計するか RailsにはDBに依存しないActiveModelや、ValueObjectを実現するcomposed_ofな ど、ビジネスロジックを凝集する独自のエコシステムがある。従ってRailsならではの方法 でコアドメインを構成する手段があってもいいのでは、と考える。 もう一度おさらい。DDDの目的は、コアドメイン(中心的問題領域)を解決するロジックの ビジネス価値向上(収益最大化)と、開発生産性の向上(開発コスト低減)である。この 目的を達成できれば、極論手段は何でもいいはず。 鵜呑みにしてはいけない。立ち止まってはいけない。我々は技術での課題解決を生業と するエンジニアである。
巨大Railsレガシーの技術的負 債にDDDで対処 ドメイン層を追加。 ビジネスロジックをドメイン層へ凝集するリファク タリングを実施。 詳細はQiitaの「ドメイン駆動設計の比類なきパ ワーでRailsレガシーコードなど大爆殺したるわ あああ!!!」 (https://qiita.com/MinoDriven/items/3c7db287 e2c66f36589a)
良かったこと 技術的負債の解消に貢献(Code Climate)。 ドメイン層へ凝集したコードが異常に追跡しやすくなった。 永続化など他の関心事とは隔離され、混乱が低減。 リファクタリングの途中で、それまで隠れていたビジネス概念を発見。隠れた仕様の掘り 起こしに成功。 設計未経験の新人にレクチャーしながらリファクタリング。わずか3ヶ月でOOPの利点を 踏まえた設計提案や、同じ目線でDDDを議論できるレベルにアップ。
辛いこと ActiveRecordからニョキニョキ生えてくるbuild_xxxやcreate_xxx。ヤツがいるせいで影 響範囲の把握が困難。 callback地獄。after_saveで他のモデルをupdateしてると変更追跡が困難。 静的型付け言語ならIDEで参照検索できるのに、検索手段がgrepとか苦悶。名前がカ ブると詰む。ユニークな命名必須。 ViewとActiveRecordの密結合が最凶の敵。Railsは結合度を犠牲にスタートアップ加速 力を得た犠牲的アーキテクチャ。この密結合の影響でバックエンドの負債解消も困難に なっている箇所がある。 Rails-wayから外れるのは相当な苦行であることに違いはない。
DDDの向き不向き DDDは、サービスのライフサイクル全体を通じて継続的に価値向上目指す、長期開発 力を主眼にしている。そのため、プロトタイプなど短命のソフトウェアや、コード変更され ない寿命間近のサービスには適さない。コストがかかるだけ。 DDDの実践にはビジネス理解が必須。なぜならドメインモデリングにはビジネス理解が 必須だから。「私は技術には興味ありますけど、ビジネスには興味ありません。仕様はビ ジネス側で考えて下さい」といった考えをお持ちなら厳しい。DDDを実践したいならビジ ネス課題に目を向けましょう。(尺の問題上この資料では説明しないが)また、DDDに関 係なく、ビジネスの理解は単一責任原則を遵守した設計に貢献する(むしろ必須)。
DDDの向き不向き ドメインモデルの継続的な価値向上のため、継続的にリファクタリングしていく必要があ る。静的型付け言語ではIDEなどの静的解析機能により、リファクタリングの正確性、速 度の面において有利。一方Rubyなど動的型付け言語では静的解析の精度が落ちてし まい、速く正確にリファクタリングを回していけないため、DDDに不向きとは言えないま でも、課題感がある。
まとめ サービスには中心的価値となるコアドメインがある。 ドメイン駆動設計は、コアドメインのビジネス価値と開発生産性を継続的に向上させる設 計手法である。 DDDではドメイン層を用意し、コアドメインを解決する重要ビジネスロジックをドメイン層 へ実装し、他と隔離するのが特徴。
まとめ DDDではドメイン層を用意する構造ゆえ、Rails新規開発でのDDDは全くオススメでき ない。Rails-wayから外れ、苦しくなる。 しかしDDDの何もかもがRailsに貢献できない、というのは違う。極端。 巨大化したRailsレガシーサービスの技術的負債解消や、喪失したコアドメインを捜索す る上でDDDの考え方やアプローチは大きな手助けになる。 その場合、DDD本書に記載の「エヴァンス流」設計手法をそのまま鵜呑みにしてRailsへ 適用するのは課題がある。Railsならではのやり方へテーラリングしたり、よりよい設計 方法を模索することが何よりも大事。