C4モデル図とは何ですか?
The C4モデル図は、ソフトウェアアーキテクチャをさまざまな詳細レベルで文書化することを目的とした階層的で4段階のアーキテクチャフレームワークです。シモン・ブラウンによって作成されたC4は、システムマップを4つの明確な抽象化のレンズに構造化することで、曖昧なボックスや線を回避します:コンテキスト(システムレベルの範囲)、コンテナ(アプリケーションおよびデータストア)、コンポーネント(内部モジュール)、およびコード(クラスレベルの実装)。
このモデルをテキストで効果的に実装するため、エンジニアは公式のC4-PlantUML標準ライブラリ拡張を使用します。このライブラリは、ユーザー、システム、データベース用に異なる色、形状、メタデータフィールドを自動挿入する専用マクロで、原始的なUML形状を置き換えます。VPasCodeを使用すれば、これらのネストされた環境をコード上で明確に定義できます。レイアウトエンジンは、接続ベクトルを動的にルーティングし、テキストフィールドをスケーリングしながら、レイアウトの幾何学的構造を損なうことなく処理します。
コア構文ガイド:要素と構造
PlantUMLを使用して有効なC4モデルを構築するには、正しいライブラリファイルをインポートし、構造的マクロを選択し、境界を設定し、専用の関係リンクを使用する必要があります。
1. C4標準ライブラリファイルのインポート
The C4-PlantUML拡張機能は、抽象化モデルの異なるレベルに直接対応する個別のファイルに分割されています。パフォーマンスの低下やコンパイラエラーを防ぐため、図に必要な特定のファイルレイヤーのみをインポートするようにしてください:
@startuml
' 必要な特定のC4レイヤーファイルを含める
!include <C4/C4_Context>
' より深いアーキテクチャマップにはC4_ContainerまたはC4_Componentを使用する
2. コアアクターとシステムの宣言(コンテキストレベル)
高レベルのシステムコンテキスト層では、内部コンポーネント、外部依存関係、および人間のエンドユーザーをモデル化します。標準ライブラリには、ID、視覚的ラベル、およびオプションの説明タグを受け取る特定のマクロが用意されています:
Person(id, "ラベル", "説明")— 人間のユーザープロファイルまたはシステムアクターを表します。System(id, "ラベル", "説明")— 主な内部ソフトウェアアプリケーションまたはサービスエコシステムを表します。System_Ext(id, "ラベル", "説明")— 外部システムまたはサードパーティAPIの依存関係を表します(明確なグレー色のパレットでレンダリングされます)。
@startuml C4_Elements
!include <C4/C4_Context>
Person(customer, "銀行顧客", "個人の銀行口座を持つ顧客")
System(banking_sys, "コア銀行システム", "金融取引を処理")
System_Ext(mail_sys, "メールサービス", "内部SMTP通知ゲートウェイ") 
3. バウンダリーの展開(コンテナおよびコンポーネントレベル)
コンテナ層をさらに深く掘り下げる際には、Webアプリ、マイクロサービス、データベースをモデル化します。これらの内部要素を明確な論理的な境界ボックス内に分離するには、System_Boundary()マクロラッパーを使用します:
!include <C4/C4_Container>
System_Boundary(c1, "ECシステムエコシステム") {
Container(web_app, "シングルページアプリケーション", "React & TypeScript", "Webビューを通じてユーザー機能を提供")
ContainerDb(database, "リレーショナルデータベース", "PostgreSQL", "ユーザーのプロフィールと取引履歴を保存")
} 
4. 技術的関係のマッピング
基本的な破線に頼るのではなく、C4は明確な通信マクロ形式を採用しています:Rel(From_ID, To_ID, "ラベル", "技術")これにより、すべての接続がその目的と下位のトランスポートプロトコル(HTTPS、gRPC、AMQPなど)を明示するよう強制することで、アーキテクチャマップの可読性を高めます:
!include <C4/C4_Container>
Person(customer, "銀行顧客", "個人の銀行口座を持つ顧客")
System(banking_sys, "コア銀行システム", "金融取引を処理")
System_Ext(mail_sys, "メールサービス", "内部SMTP通知ゲートウェイ")
System_Boundary(c1, "ECシステムエコシステム") {
Container(web_app, "シングルページアプリケーション", "React & TypeScript", "Webビューを通じてユーザー機能を提供")
ContainerDb(database, "リレーショナルデータベース", "PostgreSQL", "ユーザーのプロフィールと取引履歴を保存")
}
Rel(customer, web_app, "ストアフロント機能を以下を通じて利用", "HTTPS")
Rel(web_app, database, "トランザクションデータを以下を通じて読み書き", "SQL/TCP") 
可読性の高いC4アーキテクチャのためのベストプラクティス
- 抽象レベルを混同しない:図を単一のレイヤーに集中させましょう。高レベルのシステムコンテキストマップに細かい内部ソフトウェアコンポーネントを混在させないでください。システムが複雑になりすぎた場合は、別途専用のコンテナレベルの図に分割してください。
- 技術を明確に定義する:常にマクロの4番目のパラメータを活用して、使用されている正確な技術またはプロトコルを明記してください(例:
Rel()マクロを使用して、使用されている正確な技術またはプロトコルを明記してください(例:"JSON/HTTPS"または"JDBC").これにより、チームは実装の重要な文脈を一目で把握できます。 - 方向性レイアウトオーバーライドを活用する: コンポーネントが不自然に重なってきている場合は、方向性関係マクロ(例:
Rel_D()下方向用、Rel_R()右方向用、またはRel_L()左方向用)を使用して、アーキテクチャフローを手動で整理してください。
実際のPlantUML C4の例
例1:高レベルシステムコンテキストレイアウト(レベル1)
この機能的ブループリントは、標準的なレベル1システムコンテキスト図をモデル化しており、顧客がインターネットバンキングアプリケーションとその外部依存関係との間でどのように相互作用するかを詳細に示しています。
@startuml
!include <C4/C4_Context>
title インターネットバンキングシステムのシステムコンテキスト図
Person(customer, "個人銀行顧客", "個人口座を持つ銀行の顧客。")
System(banking_system, "インターネットバンキングシステム", "顧客が金融情報を閲覧し、送金を行うことを可能にする。")
System_Ext(mail_system, "メールサブシステム", "企業内での内部送信クラスタであるSendGridの企業メールサーバー群。")
Rel(customer, banking_system, "オンラインダッシュボード経由で利用")
Rel_R(banking_system, mail_system, "アラートや認証コードを送信する際の使用", "SMTP")
@enduml 
構文の分解: この図は高レベルの範囲にのみ焦点を当てています。System_Ext マクロはメールサービスに自動的にグレーの色プロファイルを適用し、コアシステムと外部依存関係を視覚的に分離します。Rel_R マクロはレイアウトエンジンに、メールノードをバンキングシステムブロックの右側に直接配置するよう強制します。
例2:マイクロサービスコンテナトポロジーの詳細分析(レベル2)
この高度なエンタープライズブループリントは、システムを構成するコンテナアプリケーションと分離されたデータストアに分解し、WebトラフィックがAPIゲートウェイを経由してバックエンドのマイクロサービスまでどのようにルーティングされるかを示しています。
@startuml
!include <C4/C4_Container>
title 支払いポータルゲートウェイのコンテナ図
Person(merchant, "Webマーチャントパートナー", "プラットフォームのチェックアウトエンドポイントを自社ウェブサイトに統合する。")
System_Boundary(portal_scope, "支払いゲートウェイエコシステム") {
Container(api_gateway, "APIルーティングプロキシ", "Nginx", "インバウンドコールをインターセプトし、レートリミットを処理し、ノードをバランスする。")
Container(auth_service, "アイデンティティマイクロサービス", "Go & OAuth2", "開発者用APIトークンとスコープを検証する。")
Container(txn_service, "取引台帳", "Java Spring Boot", "支払い処理と台帳アカウントの管理を行う。")
ContainerDb(ledger_db, "台帳データストア", "CockroachDB", "分散型ACID準拠のテーブルスキーマを実装する。")
}
' 内部コンテナターゲット間を滑らかにルーティングするトラフィックフロー
Rel(merchant, api_gateway, "HTTPS/JSON経由で支払いペイロードを送信")
Rel_D(api_gateway, auth_service, "gRPC経由で受信トークンを検証")
Rel_D(api_gateway, txn_service, "gRPC経由でチェックアウトアクションを転送")
Rel_R(txn_service, ledger_db, "SQL/TLS経由で台帳エントリを永続化")
@enduml 
構文の分解: 以下のマクロラッパーを使用することで、System_Boundary マクロラッパーを使用すると、内部コンポーネントが明確な境界ボックス内にきれいにグループ化されます。特別なContainerDb マクロは明確なデータベースシリンダーのアイコンでデータストアを描画し、コンピュートランタイム層と永続ストレージ層の区別を一目で明確にします。