Slide 1

Slide 1 text

Railsで考える ドメイン駆動設計の コアドメイン 2020/10/23(金) 銀座Rails#26 ミノ駆動 (@MinoDriven)

Slide 2

Slide 2 text

アジェンダ ● 自己紹介 ● 本スピーチの目的 ● ドメイン駆動設計の「ドメイン」とは ● コアドメインとは ● コアドメインの価値向上手法 ● DDD実現手段とRailsへの応用、その考え方 ● 巨大Railsレガシーの技術的負債にDDDで立ち向かった例 ● DDD向き不向き ● まとめ

Slide 3

Slide 3 text

自己紹介 ● ミノ駆動(@MinoDriven) ● リファクタリング大好き。 ● クソコードを滅ぼす技術が大好き。 ● たまに夢の中でもリファクタリング… ● ㈱クラウドワークスではリファクタリングや設計が主任 務。 ● 巨大Railsレガシーの技術的負債に対し、DDDベースに リファクタリング実践中。

Slide 4

Slide 4 text

職歴 1社目 ㈱NECネットワーク・センサ:ファームウェア、電子回路 設計 2社目 キヤノン㈱:医療X線撮像ソフトウェア、工場監視用画 像処理サーバの開発、リファクタリング 3社目現職 ㈱クラウドワークス:「自社のRailsレガシーがヤバ いのでリファクタリングしてほしい」とTwitter上でナンパされ入 社 ● C#を十数年、その他CやC++で組み込みやWindowsネイ ティブの開発経験が長いです。 ● Web系はまだ1年半ほど。Rails含めてWeb周辺技術は 全然浅いです。

Slide 5

Slide 5 text

Qiita

Slide 6

Slide 6 text

クソコード動画

Slide 7

Slide 7 text

バグ退治RPG「バグハンター2 Reboot」制作中

Slide 8

Slide 8 text

ドメイン駆動設計とは エリック・エヴァンス氏が考案した設計手法。 ドメインモデルのモデリングを中心に、ソフトウェア 開発に伴う複雑さを解決する。 長期的な開発力向上に威力を発揮すると言われて いる。 特にマイクロサービス化ではほぼほぼセットで語ら れる。

Slide 9

Slide 9 text

ドメイン駆動設計に対するイメージ なんだか 難しそう… 設計パターン集? Railsでは 無理 アカデミックな理論で 実用性なし 机上の空論

Slide 10

Slide 10 text

RailsではDDDは難しい? お互いの良さを 殺してしまう Rails-wayから 外れてしまう DDDやりたいなら はじめから Rails使うな 型がなくて つらい

Slide 11

Slide 11 text

ちょっと待て コアドメインはどこに行った

Slide 12

Slide 12 text

コアドメインが語られない違和感 DDDを採用するかどうかとか、RailsでDDDは困難とか議論する 以前に、そもそもDDDのコアドメインが議論されているのをあまり 見聞きしたことがない。 DDDではコアドメインが真の主人公なのに!!

Slide 13

Slide 13 text

軸がなくフワフワと漂う議論 何のためにDDDで設計するか、その議論はコアドメインを意識す ることが必須。 しかしコアドメインがすっぽ抜けているために、DDDは「設計パ ターン集なんでしょ」とか「アーキテクチャが合わないから無理」と か(私から見ると)いまいち議論の軸が定まっていないように見え る。

Slide 14

Slide 14 text

目的 そこで本日はDDDの真の主人公コアドメインを中心に、ドメイン駆 動設計で解決したいことの理解を目的とします。 その上で、RailsとDDDとの関係や、どう応用するかについて考え るキッカケを皆様にご提供することを目的とします。

Slide 15

Slide 15 text

まずはRailsから離れて ソフトウェア開発全般の事柄として 聞いて下さい。 (※あとでRailsの話をします)

Slide 16

Slide 16 text

DDD序文 DDD序文より引用。いの一番でコアドメインが登場している。 「境界付けられたコンテキスト」や「ユビキタス言語」は頻繁に議論されるが、どういうわ けかコアドメインだけが空気扱い。

Slide 17

Slide 17 text

「コアドメイン」って何よ? …の前に、 ドメイン駆動設計の 「ドメイン」とは。

Slide 18

Slide 18 text

ドメイン(問題領域): RPGを楽しみたい 解決領域: ドラゴンクエスト 解決領域: ファイナルファンタジー メラ メラミ ファイア メラ ゾーマ ファイラ ファイガ ドメインモデル: ActiveRecordではない。 ドメインの課題を解決するモデルであり、物事の特定の側面を抽象化したもの。 ドメイン課題を効果的に解決するための 変換能力を備えた概念。変換能力がなければド メインモデルとは呼べない。

Slide 19

Slide 19 text

問題領域: RPGを楽しみたい 様々な戦い方、成長を 楽しみたい アイテムコンプ したい 魔法で 戦いたい 解決領域: ドラゴンクエスト 武闘家 バイ キルト 小さな メダル 盗賊 賢者 ニフラム メド ローア ドメインには、さらに個々のドメイン(問題領域)がある。 各問題領域の解決に貢献するドメインモデルがいる。

Slide 20

Slide 20 text

問題領域: SNSを楽しみたい 情報収集 話題性 コンテンツ 健全性 解決領域: Twitter ブック マーク ミュート リツイート モーメント リスト ブロック 通報 Twitterの例 いいね フォロー

Slide 21

Slide 21 text

皆さんそれぞれが 開発しているサービスの ドメインやドメインモデルを 考えてみましょう。 個々の問題領域を 思い浮かべましょう。

Slide 22

Slide 22 text

イメージできました?

Slide 23

Slide 23 text

…と、 ここでいきなり経営者視点

Slide 24

Slide 24 text

どこに開発リソースを投じるか? 開発リソースは有限です。 限られた予算、時間、人材の中で、開発に投資しなければいけま せん。 サービスには対象とする問題領域が様々あります。 どこの問題領域に投資すれば顧客の課題を解決し、顧客に訴求 し、大きく利益を得られるでしょうか?

Slide 25

Slide 25 text

どこが費用対効果が高い? あのニーズ? それとも別の顧客課題?

Slide 26

Slide 26 text

あなたのサービスの ウリは何ですか?

Slide 27

Slide 27 text

それこそが コアドメイン

Slide 28

Slide 28 text

コアドメインとは システム内で最大の価値を付加すべき場所。 価値があり重要で、費用対効果が最大の箇所。 競争優位性があり、差別化が図られ、ビジネス上優位に立つポイント。 優位に立つため設計の一部を秘密にしておく場合もある。 コアドメインの名の通り、ビジネスの中心的な問題領域。 問題領域 コアドメイン 汎用 サブドメイン 支援 サブドメイン

Slide 29

Slide 29 text

自分たちのサービスがいまいち顧客に訴求しない …。折角開発したのに顧客にウケない…。利益が上 がらない。 自分たちのサービスのウリは分かっている。もっとウ ケるように次々新しい仕様を盛り込みたい。でもウリ の部分がクソコードすぎて、スピーディーに開発でき ない…。開発コストだけがいたずらに増大する。 こんな課題を解決するのがドメイン駆動設計。

Slide 30

Slide 30 text

ドメイン駆動設計の目的 ドメイン駆動設計は、コアドメインについて、以下2点の継続的な向 上を目指し、サービスを継続的に利益体質にする設計思想である。 ビジネス価値:コアドメインのビジネス価値を向上し、顧客に訴求し (つまりバカウケし)、サービス利益の最大化を図る。 開発生産性:コアドメインを構成するモジュールの変更容易性を高 め、低コストでスピーディーにコアドメインの価値を向上する。

Slide 31

Slide 31 text

有名サービスの コアドメインは何かを 考えてみる ※登壇者の私見、解釈であり、 実際とは違う可能性が多分にあります

Slide 32

Slide 32 text

Twitter のコアドメインは?

Slide 33

Slide 33 text

問題領域: SNSを楽しみたい 情報収集 話題性 コンテンツ 健全性 解決領域: Twitter ブック マーク ミュート リツイート モーメント リスト ブロック 通報 いいね フォロー 話題性に貢献する、他にはない 非常に特徴的なモデル おそらく コアドメイン

Slide 34

Slide 34 text

リングフィットアドベンチャー のコアドメインは?

Slide 35

Slide 35 text

問題領域: フィットネスゲームを楽しみたい 飽きずに 続けたい 解決領域: リングフィットアドベンチャー リング君 フィット スキル ステージ ギミック プレイヤーの運動動作を モンスターへの攻撃に変換する 非常に画期的なモデル おそらくコアドメイン (開発者インタビューの内容より ) アドバイザであり、 心理的にサポートするメンター 道中の様々なギミックの正 体は、動的なフィットネスメ ニュー。

Slide 36

Slide 36 text

なぜコアドメインとそれ以外を区別するか 開発リソースが有限だから。費用対効果を最大化したいから。 サービスが巨大化してくると、サービスの中心的な価値が何であるか、だんだん分から なくなってくる。 費用対効果を高め、差別化を図って競争優位性を得るには、何が自分たちの中心的価 値かを理解するのが肝要。サブ的要素や的外れな要素に投資してもリターンは薄い。 著者エヴァンス氏「手の込んだ設計を、あらゆる詳細への適用を推奨しているわけでは ない。重要な箇所に集中する」(意訳「全部DDDでやれとは言ってない」

Slide 37

Slide 37 text

エヴァンスさんが考案した コアドメイン価値向上の手法

Slide 38

Slide 38 text

①ビジネス価値向上に関連する手法(一部抜粋) 手法 説明 ドメインエキスパート 問題領域に関して深い知識を持つメンバー。 ドメインビジョン声明文 コアドメインの価値を簡潔に説明した文書。 深いモデル コアドメインの本質的課題の解決に大きく貢献する、重要モデル。 暗黙的概念 本質理解に重要だが、明示的に示されない隠れた概念。 ユビキタス言語 ビジネス概念を噛み砕き、ソフトウェアが解決したい本質的概念を理解する ための言語。 顧客のニーズに訴求し利益を増大するには、顧客課題の本質を理解し、 その本質的課題を解決するドメインモデルを発見・発明・改良しなければ ならない。 フィット スキル リツイート コアドメインと同様にドメインモデルの価値向上も DDDの議論であまり語られない!でも超重要!!

Slide 39

Slide 39 text

②開発生産性向上に関連する手法(一部抜粋) 手法 説明 ユビキタス言語 関係者全員の意思疎通の精度とコストパフォーマンス向上に貢献。 ドメイン層 UIやDBなど他の技術レイヤから隔離され、問題領域の課題解決に貢献す るピュアな層。コアドメインの構成要素を他から隔離する。 Repository 永続化ロジックをドメインロジックから隔離する設計パターン。 ValueObject 値の振る舞いを表現する、 DDDで基本にして重要なパターン。 コアドメインを解決するロジックが低凝集密結合なクソコードになっていると、折角ビジネ スチャンスがあってもすぐに変更できず、市場要求に素早く対応できなくなる。また、コア ドメインに貢献する概念(ドメインモデル)に相当するロジックを発見したり、改良するの が困難になる(やりたいことはむしろコレ)。 だから以下各種設計手法を用い、コアドメインのロジックをクリーンな構造にして開発生 産性を向上させなければならない。

Slide 40

Slide 40 text

ここで唐突に質問です

Slide 41

Slide 41 text

世の中には様々なサービスがあります。 どのサービスにも、それぞれウリになる部分があります。 つまり、コアドメインが存在します。

Slide 42

Slide 42 text

でもどのサービスがRails製で、どのサービスが非 Rails製か、パッと見で見分けがつきますか?

Slide 43

Slide 43 text

JavaだからSpringBootだからコアドメインがある、 Railsだからコアドメインがない、ではないはず。それ らは実装方法の違いに過ぎません。 ゆえにRailsアプリにも、対象とするコアドメインがあ ります。

Slide 44

Slide 44 text

サービスのウリになる部分を 把握していますか?

Slide 45

Slide 45 text

ウリの部分の設計は クリーンですか? 高い開発生産性を出せる、 変更コストが低い設計に なっていますか?

Slide 46

Slide 46 text

View Controller ActiveRecord ActiveRecord ActiveRecord :重要ビジネスロジック 重要ビジネスロジックがあちこち に散在している。 そのため、サービスの中心的価 値が何なのか、ロジックレベルで 認識困難な状態。 関係し合う重要ロジックや影響 範囲を探し回らないといけない ため、高い開発生産性を出せな い。

Slide 47

Slide 47 text

View Controller ActiveRecord Domain ActiveRecord ActiveRecord :重要ビジネスロジック 重要ビジネスロジックをドメイン 層に凝集。他の関心事(例え ばUI制御やDB制御)から隔離 する。 サービスの中心的価値を認識 しやすくなる。 関係し合う重要ロジックがドメ イン層内で整理されていること で高い開発生産性を出せる。 注文 予約 割引金額 クリスマス キャンペーン 特別会員価格

Slide 48

Slide 48 text

View Controller ActiveRecord ActiveRecord :重要ビジネスロジック Rails新規開発では始めから何をウ リにするか狙いを立ててるから、そ もそもコアドメインを喪失していな い。 コアドメインを解決する重要ロジック が散らばっていることもないから、 DDDでやる価値が薄い。 そもそもRails-wayに乗る利点が薄 れてしまう。

Slide 49

Slide 49 text

DDD実現手段に関するエヴァンス氏の見解 DDDはコアドメインの価値を高めるため、コアドメインを構成 するロジックをドメイン層へ隔離し、ドメインモデルをドメインオ ブジェクトとして設計実装するのを実現の主眼としている。 実現手段は、オブジェクト指向言語がやりやすい、と言ってる だけで、それ以外じゃダメだとは言ってない。手続き型言語で も限定的には可能。 DDDに登場するパターン以外にも、GoFのデザインパターン で使えるものが様々あり、活用できることは素晴らしい、と述 べている。

Slide 50

Slide 50 text

DDD実現手段を巡る解釈 Aggregate、ValueObjectなど、DDDで紹介されているパターンは、「こうすればDDDを 実現しやすい」とエヴァンス氏が考案した手段のひとつに過ぎない。 先の手続き型言語やGoFに対する見解も加味すると、Rails流のDDD実現手段が編み 出されてもいいのでは?と考える。

Slide 51

Slide 51 text

エヴァンス氏に関係なく我々がどう設計するか エヴァンス氏はエンジニアの一人であり、何が何でも彼の設計方針通り全て従わなけれ ばならない理由はない。 設計界隈では、DDDに関してより実用的に改善する動きがある。例えばユースケース 層を設けたり(※1)、「ドメインじゃ分かりにくいから『人の営み』と呼称しよう(※2)」など。 ※1:松岡幸一郎氏( @little_hand_s )「ドメイン駆動設計 モデリング/実装ガイド」( https://booth.pm/ja/items/1835632 ) ※2:林宏勝氏( @hirodragon112 )「概念投影によるオブジェクト指向設計の考え方とその方法」 ( https://speakerdeck.com/hirodragon112/conceptual-projection-design )

Slide 52

Slide 52 text

エヴァンス氏に関係なく我々がどう設計するか RailsにはDBに依存しないActiveModelや、ValueObjectを実現するcomposed_ofな ど、ビジネスロジックを凝集する独自のエコシステムがある。従ってRailsならではの方法 でコアドメインを構成する手段があってもいいのでは、と考える。 もう一度おさらい。DDDの目的は、コアドメイン(中心的問題領域)を解決するロジックの ビジネス価値向上(収益最大化)と、開発生産性の向上(開発コスト低減)である。この 目的を達成できれば、極論手段は何でもいいはず。 鵜呑みにしてはいけない。立ち止まってはいけない。我々は技術での課題解決を生業と するエンジニアである。

Slide 53

Slide 53 text

巨大Railsレガシーの技術的負 債にDDDで対処 ドメイン層を追加。 ビジネスロジックをドメイン層へ凝集するリファク タリングを実施。 詳細はQiitaの「ドメイン駆動設計の比類なきパ ワーでRailsレガシーコードなど大爆殺したるわ あああ!!!」 (https://qiita.com/MinoDriven/items/3c7db287 e2c66f36589a)

Slide 54

Slide 54 text

良かったこと 技術的負債の解消に貢献(Code Climate)。 ドメイン層へ凝集したコードが異常に追跡しやすくなった。 永続化など他の関心事とは隔離され、混乱が低減。 リファクタリングの途中で、それまで隠れていたビジネス概念を発見。隠れた仕様の掘り 起こしに成功。 設計未経験の新人にレクチャーしながらリファクタリング。わずか3ヶ月でOOPの利点を 踏まえた設計提案や、同じ目線でDDDを議論できるレベルにアップ。

Slide 55

Slide 55 text

辛いこと ActiveRecordからニョキニョキ生えてくるbuild_xxxやcreate_xxx。ヤツがいるせいで影 響範囲の把握が困難。 callback地獄。after_saveで他のモデルをupdateしてると変更追跡が困難。 静的型付け言語ならIDEで参照検索できるのに、検索手段がgrepとか苦悶。名前がカ ブると詰む。ユニークな命名必須。 ViewとActiveRecordの密結合が最凶の敵。Railsは結合度を犠牲にスタートアップ加速 力を得た犠牲的アーキテクチャ。この密結合の影響でバックエンドの負債解消も困難に なっている箇所がある。 Rails-wayから外れるのは相当な苦行であることに違いはない。

Slide 56

Slide 56 text

DDDの向き不向き DDDは、サービスのライフサイクル全体を通じて継続的に価値向上目指す、長期開発 力を主眼にしている。そのため、プロトタイプなど短命のソフトウェアや、コード変更され ない寿命間近のサービスには適さない。コストがかかるだけ。 DDDの実践にはビジネス理解が必須。なぜならドメインモデリングにはビジネス理解が 必須だから。「私は技術には興味ありますけど、ビジネスには興味ありません。仕様はビ ジネス側で考えて下さい」といった考えをお持ちなら厳しい。DDDを実践したいならビジ ネス課題に目を向けましょう。(尺の問題上この資料では説明しないが)また、DDDに関 係なく、ビジネスの理解は単一責任原則を遵守した設計に貢献する(むしろ必須)。

Slide 57

Slide 57 text

DDDの向き不向き ドメインモデルの継続的な価値向上のため、継続的にリファクタリングしていく必要があ る。静的型付け言語ではIDEなどの静的解析機能により、リファクタリングの正確性、速 度の面において有利。一方Rubyなど動的型付け言語では静的解析の精度が落ちてし まい、速く正確にリファクタリングを回していけないため、DDDに不向きとは言えないま でも、課題感がある。

Slide 58

Slide 58 text

まとめ サービスには中心的価値となるコアドメインがある。 ドメイン駆動設計は、コアドメインのビジネス価値と開発生産性を継続的に向上させる設 計手法である。 DDDではドメイン層を用意し、コアドメインを解決する重要ビジネスロジックをドメイン層 へ実装し、他と隔離するのが特徴。

Slide 59

Slide 59 text

まとめ DDDではドメイン層を用意する構造ゆえ、Rails新規開発でのDDDは全くオススメでき ない。Rails-wayから外れ、苦しくなる。 しかしDDDの何もかもがRailsに貢献できない、というのは違う。極端。 巨大化したRailsレガシーサービスの技術的負債解消や、喪失したコアドメインを捜索す る上でDDDの考え方やアプローチは大きな手助けになる。 その場合、DDD本書に記載の「エヴァンス流」設計手法をそのまま鵜呑みにしてRailsへ 適用するのは課題がある。Railsならではのやり方へテーラリングしたり、よりよい設計 方法を模索することが何よりも大事。