Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RDRAとDDDでGoのモジュラーモノリスアプリを設計してみた話

Imamoto Hikaru
September 15, 2022

 RDRAとDDDでGoのモジュラーモノリスアプリを設計してみた話

Imamoto Hikaru

September 15, 2022
Tweet

More Decks by Imamoto Hikaru

Other Decks in Programming

Transcript

  1. #modelinglt フェーズごとの戦略 フェーズ 戦略 効果 要件定義 RDRA (リレーションシップ駆動要求分析 ) ・要求元の要求と整合性を取る形で、

     業務やビジネスユースケースを洗い出し ・業務フロー図+UC複合図で  必要な画面やシステムの機能洗い出し ・要求元との要件合意の迅速化 設計 DDD (ドメイン駆動設計) ・RDRAをインプットとした  コンテキスト分割やドメイン名 ・コンテキストマップで責務を集約 実装 Goでモジュラーモノリス (WorkspaceModeを使用) ・コンテキストマップ上のコンテキスト名や  コンテキスト間の依存関係を元に  そのままモジュール化できる ・モノレポでデプロイを 1つのアプリとなるが、  モジュール分割しているので並行開発も容易
  2. #modelinglt 要件定義フェーズ:RDRAを実践 • RDRA(リレーションシップ駆動要求分析)とは ◦ 神崎善司さん(@zenzengood)が提唱している要件分析手法 ▪ 本資料での説明も RDRA2.0ハンドブック を参考にしています。

    ◦ 要件定義には4つの視点があり、RDRAではそれぞれの視点を「レイヤー」 として定義 ▪ システム価値>システム外部環境>システム境界>システム ◦ 上位レイヤーは下位レイヤーの”Why”となり、下位レイヤーは上位レイヤー の”What”となる ◦ 上位レイヤーから要求分析することで、網羅的な要件定義が可能
  3. #modelinglt レイヤーごとの視点 • システム価値レイヤー ◦ システムが「誰にとっての価値を実現するのか」を明らかにする ▪ 関連するアクターや外部システム、システム化目的等を定義 • システム外部環境レイヤー

    ◦ システムが「どのように使われるのか」を明らかにする ▪ 業務やビジネスユースケースを洗い出し、業務フローや利用ケースを定義する • システム境界レイヤー ◦ システムと「どう関わるか」を明らかにする ▪ 誰がどのようにシステムを利用するかや、システムの処理の単位(ユースケース)を定義する • システムレイヤー ◦ システム化する「情報」とその情報が取り得る「状態」でシステムを明示する
  4. #modelinglt RDRAの表現手法と記述例 • アイコン ◦ レイヤーごとに定義されるモデルを 表す • ダイアグラム ◦

    レイヤーごと明らかにすべき事柄を 示すための図 • 右図はシステムコンテキスト図 ◦ 「システムコンテキスト図」はシステム 価値レイヤーで定義されるダイアグラ ム ◦ システムに関わるアクター、外部シス テムをアイコンとして定義する ◦ システム化の目的を認識合わせする
  5. #modelinglt RDRAを実践してみた感想 • 「要件定義」にとどまらず「基本設計」まで踏み込んだドキュメント が完成される ◦ 内容が具体的になるので要求元との要件合意がより迅速・明確にできる ◦ 入社直後の私にとっては社内システムやルールの学習にも有用だった •

    「業務」や「ビジネスユースケース」の分割は難しい ◦ 最終的には決めの問題なので、試行錯誤して決定する必要がある • ビジネスとシステムのバランス感覚が必要 ◦ システムに寄りすぎると、ビジネス側の人に内容を理解してもらえない
  6. #modelinglt 設計フェーズ:DDDを実践 • DDD(ドメイン駆動設計)とは ◦ ドメイン(≒システム化対象となる業務の世界)の専門家からの入力を元に、ドメインの世界 に一致するようにドメインをモデル化する設計手法 • 戦略的DDD ◦

    ドメインをモデリングするための設計戦略 ▪ 境界づけられたコンテキスト、ユビキタス言語の定義等 • 戦術的DDD ◦ 設計した内容を実装するためのモデリング ▪ エンティティや値オブジェクトを定義するドメインモデリングはここに属する
  7. #modelinglt 戦略的DDDの実践 • コンテキストマップの作成 ◦ RDRAの「ビジネスコンテキスト」「業務フロー+UC複合図」を主なインプットとして、 分割できる業務領域を洗い出して境界付けられたコンテキストを定義 ◦ コンテキスト間の依存関係も含めたコンテキストマップを作成 ▪

    コンテキスト間が相互依存or循環参照にならないように設計 ◦ コンテキストごとの責務を明確化してコンテキストマップに付記 • ユビキタス言語となる用語集の作成 ◦ RDRAの「情報モデル」を主なインプットとして、コンテキストごとに「用語説明」とい う形で主なユビキタス言語を付記
  8. #modelinglt DDDを実践してみた感想 • 前フェーズのRDRAの資料をインプットとして活用できた点が良かった ◦ RDRAで基本設計まで踏み込んでいるので、モデリングがしやすかった ◦ 開発のためのDDDから一歩前進できた • テキストベースでの用語説明や設計意図説明も残しておいた方が良い

    ◦ 「ドメインモデル図さえあれば実装できる!」という人はドメインモデルの作成者しかいな い • mermaid.jsを使ってmarkdownファイル内で書いたので、レビューもし てもらいやすかった ◦ GitHubがmermaidの自動レンダリングに対応している
  9. #modelinglt 実装フェーズ:Goでモジュラーモノリス • Goには「module」というコード管理 単位が存在 • go.modというファイルにmodule名 や依存するmoduleを記載 • go.modが置かれているフォルダ配下

    はすべて同moduleに属する • ただしサブフォルダに別のgo.mod ファイルが置かれている場合は、別の moduleとなる • module間の依存解決の手段として Workspace modeを利用 Main Module Module A Module B Main Module Workspace 管理
  10. #modelinglt 実装の基本方針 • 設計時に定義したコンテキストの単位でGo Moduleを作成することで、モジュ ラーモノリスを実現する ◦ Module名やModule間の依存関係はコンテキストマップを踏襲 ◦ 1つのリポジトリ(モノレポ)で複数Moduleを管理

    ◦ Workspace modeで同一リポジトリ内のModuleにも依存可能 • Moduleごとにレイヤードアーキテクチャ構成にする • コンテキストごとにDBも分割 ◦ PostgreSQLで同一DBクラスタで複数DBを作成 • 外部からのHTTPSリクエストはメインのModuleで受けて、各コンテキストの UI層にリクエスト情報を渡す形でAPI呼び出しを実現
  11. #modelinglt 未来の話:モジュラーモノリスをMSA化 • 今後、必要性を感じてMSA化する場合はModuleを別リポジトリに切 り出してIN/OUTを調整することで実現可能 ◦ 作成済みのAPIを呼び出すエンドポイントを準備 ▪ UI層まで作成済みなので、工数としては大きくない ◦

    切り出したModuleのメソッドをInfrastructure層で呼び出していた箇所を、API 呼び出しに切り替える ▪ レスポンスのフォーマットは基本的に変わらず、改修箇所の特定も容易なので、工数としては大き くない ◦ DBは既に分離済みのため、大きなマイグレーション不要