de_DEen_USes_ESfa_IRfr_FRhi_INid_IDjapl_PLpt_PTru_RUvizh_CNzh_TW

C4モデル レベル3 ディープダイブ:内部構造と責任を明らかにするコンポーネント図の習得

C4コンポーネント図とは何ですか?

コンポーネント図はレベル3サイモン・ブラウンのC4モデルにおけるもので、特定のコンテナ(レベル2のコンテナ図から)を拡大して、以下を示す:

The Ultimate Guide to C4 Model Visualization with Visual Paradigm's AI  Tools - ArchiMetric

  • そのコンテナを構成する論理的な構成要素(コンポーネント)

  • これらのコンポーネントが互いにどのように相互作用するかを示す。

  • 責任および実装技術(クラスよりも高いレベルで—Spring Beans、モジュール、サービス、コントローラ、ファサードなどと考える)。

  • コンポーネント間の重要なインターフェースまたは契約(関係性からしばしば示唆される)。

重要な補足:C4における「コンポーネント」とはコンテナのように独立してデプロイ可能ではない。それはクラスの論理的グループ化であり、明確な責任を持つもので、コンテナ内ではある程度独立して開発・テスト・デプロイが可能だが、コンテナのように独立してデプロイ可能ではない

コンポーネントの例:

  • RESTコントローラ / Webコントローラ

  • サービス / ユースケース / アプリケーションサービス

  • リポジトリ / データアクセスオブジェクト

  • ドメインモデル / エンティティ

  • セキュリティ / 認証モジュール

  • 通知送信者

  • 外部システムへのファサード

  • ビジネスルールエンジン

  • キャッシュレイヤ

図は依然として論理的かつ実装に依存しない程度に— クラスの属性やメソッドのシグネチャ、完全なUMLクラス詳細は含まない(これはレベル4コードであり、オプションで稀なケースである)。

コンポーネント図を作成するタイミング

コンポーネント図を作成(および維持)する以下の状況においてのみ:

  • 選択されたコンテナは十分に複雑であるその内部構造が名前と説明だけでは明らかでないほどである。

  • 新規チームメンバー(特にバックエンド開発者)は頻繁に尋ねる:「このサービス/APIの中で、機能Xは実際にどのように実装されているのですか?」

  • あなたはリファクタリング分割、または抽出コンテナ内のロジックを処理し、境界や責任を明確にしたい場合

  • あなたは詳細な設計討論コードレビュー、またはオンコール引継ぎ特定のコンテナ向けに。

  • 以下を文書化したいとします:重要なアーキテクチャ的決定コンテナ内(例:ヘキサゴナルアーキテクチャ、垂直スライス、CQRS分離、セキュリティ強制ポイント)

  • 以下の問題を特定しました:技術的負債ゴッドクラス、または強い結合コンテナ内にあり、整理する前の状況を可視化したい。

  • モジュール構造を素早く理解する必要があるシニア開発者/アーキテクトのオンボーディングを行っている。

作成しないでください以下の目的でコンポーネント図を作成しないでください:

  • 単純なコンテナ(1つのコントローラ+1つのサービス+1つのリポジトリを持つCRUD API — 構造が明確)。

  • 大多数のマイクロサービス(多くの場合、コンテナレベルで十分なほど小さい)。

  • フロントエンドコンテナ(React/Vueアプリ — 通常、コンポーネントツリーまたはストーリーブックで示す方が適切)。

  • レベル2(コンテナ)+良いコード構造/命名規則で必要なすべての情報がすでに伝わっている場合。

Simon Brown氏の推奨:大多数のチームはレベル1+2で十分。レベル3まで進むのは、以下のコンテナのみです:複雑/リスクが高い/コア/変更頻度が高いコンテナ。

コンポーネント図を使う理由?(主な利点)

  • 内部の責任を明確化する— 責任の分離を示す(例:コントローラ vs サービス vs データアクセス vs 外部統合)。

  • 結合と依存関係を明らかにする — ゴッドコンポーネント、循環依存、インフラコードへの過度な依存を可視化する。

  • より良いオンボーディングと引き継ぎをサポートする — 開発者はすべてのソースファイルを読むよりも、モジュールの境界を素早く理解できる。

  • リファクタリングと進化をガイドする — モノリスを分割する前後や、パターン(ポートとアダプタ、垂直スライス)を導入する前の視覚的基準を提供する。

  • アーキテクチャレビューと脅威モデリングを可能にする — 検証、認可、ログ記録など、何がどこで行われるかを明確に指し示す。

  • アーキテクチャをコードとして扱う — PlantUMLに保存すると、コードベースとバージョン管理され、差分が確認可能で、PRでレビュー可能になる。

  • コミュニケーションのスケーラビリティを向上させる — シニア開発者はコンポーネントの責任に注目するが、ジュニアは新しいコードをどこに置くかに注目する。

素晴らしいコンポーネント図の作成方法(ステップバイステップ+ベストプラクティス)

  1. コンテナを1つ選択する — 最も複雑またはビジネス的に重要なものを最初に選ぶ(通常はメインAPI/バックエンドサービス)。

  2. レベル2からコンテキストをコピーする — このコンテナとやり取りする外部アクター(他のコンテナ、人物、外部システム)を含める。

  3. コンテナの境界を描く — 使用する:Container_Boundary PlantUMLで「このコンテナの中身」を明確に範囲指定する。

  4. コンポーネントを特定する — 次の質問を投げかける:

    • 内部にある主要なモジュール/Spring Bean/パッケージ/バウンデッドコンテキストは何か?

    • 外部からのリクエストはどこに到着するか?(コントローラ/ハンドラ)

    • ビジネスロジックはどこで調整されているか?

    • データはどこでアクセス・キャッシュ・検証されるか?

    • 横断的 concern(セキュリティ、ログ記録)はどこで処理されるか?

    • レガシー/外部システムへのフェイサードや腐敗防止層は存在するか?

  5. 技術と簡単な説明を追加する — 名前、技術(Spring Service、.NET Handler、Go Moduleなど)、短い目的(15語以内)

  6. 相互作用の定義 — 方向と意図(使用する、呼び出す、読み込む、イベントを発行する)を示す。このレベルではプロトコルはしばしば省略される。

  7. ベストプラクティス

    • 範囲を制限する — 図ごとのコンポーネントは最大6~12個まで。それ以上の場合 → 特定の視点をもつサブビューを作成する(例:「認証スライス」)

    • 意味のある名前を付ける — 「OrderService」よりも「Order Placement Service」を優先する。

    • クラスではなく責任を示す — すべてのクラスを列挙しない。論理的にグループ化する。

    • アイコンは控えめに使用する — 技術の明確化に役立つ場合にのみ使用する(Spring、.NETのアイコンなど)。

    • 凡例を有効にする — 新しい読者にとって役立つ。

    • レイアウトを整理する — LAYOUT_WITH_LEGEND()LAYOUT_TOP_DOWN().

    • リポジトリにバージョンを保存 — コンテナのコードの隣に.pumlファイルを配置する。

    • 繰り返し改善する — リファクタリングのスパイク時や四半期ごとのアーキテクチャ健全性チェック時に更新する。

PlantUMLの例 – インターネットバンキングシステムAPIアプリケーション(クラシック・ビッグバンク plcスタイル)

ここでは、公式のC4-PlantUMLライブラリを使用した本番環境用の例を紹介する — 実世界で最もよく参照されるサンプルである。

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

title コンポーネント図:インターネットバンキングシステム - APIアプリケーション

' カンテナレベルからのアクター/外部部品
Container(spa, "シングルページアプリケーション", "JavaScript & Angular", "ブラウザ経由でインターネットバンキングUIを提供")
Container(mobile, "モバイルアプリ", "iOS/Android", "限定的なモバイルバンキング機能を提供")
ContainerDb(database, "バンキングデータベース", "PostgreSQL", "ユーザーの設定、キャッシュデータ、セッションを保存")
System_Ext(mainframe, "コアバンキングシステム", "メインフレーム – コアアカウントおよび取引")

' ズームインするコンテナ
Container_Boundary(api, "APIアプリケーション") {
    Component(signInCtrl, "ログインコントローラ", "Spring MVC RESTコントローラ", "認証およびセッション作成を処理")
    Component(accountsCtrl, "アカウント概要コントローラ", "Spring MVC RESTコントローラ", "アカウント残高および概要を提供")
    Component(resetPwdCtrl, "パスワードリセットコントローラ", "Spring MVC RESTコントローラ", "パスワードリセットフローを管理")
    
    Component(security, "セキュリティコンポーネント", "Spring Bean", "JWTトークン、パスワードハッシュ化、ロールチェック")
    Component(accountService, "アカウント管理コンポーネント", "Spring Bean / Service", "アカウントクエリおよびビジネスルールを調整")
    Component(mainframeFacade, "メインフレームバンキングファサード", "Spring Bean", "レガシーmainframeへのアンチコーディングレイヤー")
    Component(emailNotifier, "メール通知コンポーネント", "Spring Bean", "確認メールおよびリセットメールを送信")
}

' バウンダリー内の関係
Rel(signInCtrl, security, "使用")
Rel(accountsCtrl, accountService, "使用")
Rel(resetPwdCtrl, security, "使用")
Rel(resetPwdCtrl, emailNotifier, "使用")
Rel(accountService, mainframeFacade, "使用")
Rel(accountService, database, "読み込みおよび書き込み", "JDBC")
Rel(mainframeFacade, mainframe, "使用", "XML/HTTPS")
Rel(emailNotifier, database, "ユーザー設定を読み込み", "JDBC")

' フロントエンドからの呼び出し
Rel(spa, signInCtrl, "使用", "JSON/HTTPS")
Rel(spa, accountsCtrl, "使用", "JSON/HTTPS")
Rel(spa, resetPwdCtrl, "使用", "JSON/HTTPS")
Rel(mobile, signInCtrl, "使用", "JSON/HTTPS")
Rel(mobile, accountsCtrl, "使用", "JSON/HTTPS")
Rel(mobile, resetPwdCtrl, "使用", "JSON/HTTPS")

LAYOUT_WITH_LEGEND()
LAYOUT_LEFT_RIGHT()

@enduml

このように描画される:

  • APIコンテナの周囲に明確な境界線

  • コントローラ、サービス、ファサードの論理的グループ化

  • 明確な責任

  • 重要な相互作用と依存関係

  • 読みやすさを目的とした自動凡例

PlantUMLレンダラー(オンラインまたはIDE)に貼り付け — システムに合わせて名前/技術をカスタマイズしてください。

このパターンをスタートテンプレートとしてご利用ください。目標は常に 効果的なチームコミュニケーション — 図の美しさではなく。モデリングを楽しんでください!

C4コンポーネント図リソース