modular-architecture について
モジュラーモノリスの設計と実装パターンを扱うスキルです。モジュール境界を定義する開発者向けに、ポートとアダプター、通信、データ分離、MediatR の指針をまとめています。
主な機能
- 01業務機能単位のモジュール構成
- 02ポートとアダプターアーキテクチャ
- 03同期・イベント型のモジュール通信
- 04モジュールごとのデータ分離
- 05MediatR のイベントパターン
活用シーン
- 01境界づけられたコンテキストのモジュール化
- 02モジュール間の結合の低減
- 03モジュールごとの永続化とスキーマ分離
- 04MediatR による内部イベント連携
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ melodic-software/ claude-code-plugins --skill modular-architectureインストール後、Claude Code で/modular-architectureを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/data-patterns.mdmediatr-integration.mdmodule-communication.mdports-adapters-guide.md詳細
モジュラーアーキテクチャ
このスキルを使用するタイミング
次のような場合にこのスキルを使用します。
- モジュラーモノリスアプリケーションを構成する
- モジュール間の境界(境界づけられたコンテキスト)を定義する
- モジュール間通信のパターンを設定する
- ポートとアダプター(ヘキサゴナル)アーキテクチャを実装する
- モジュール間でデータベースコンテキストを分離する
- 内部ドメインイベント向けに MediatR を構成する
キーワード: モジュラーモノリス、モジュール、境界づけられたコンテキスト、ポートとアダプター、ヘキサゴナルアーキテクチャ、モジュール間通信、データ分離、個別の DbContext、MediatR、ドメインイベント、内部イベント、モジュール境界
モジュール構造のパターン
中核となる原則
レイヤーではなく、**モジュール(ビジネス機能)**ごとにコードを構成します。各モジュールは、次の要素を独自に備えた自己完結型の垂直スライスです。
- ドメインエンティティと値オブジェクト
- アプリケーションサービスとハンドラー
- インフラストラクチャの実装
- 外部との通信に使用するデータ転送オブジェクト
標準的なモジュール構成
src/
├── Modules/
│ ├── Ordering/
│ │ ├── Ordering.Core/ # Domain + Application
│ │ │ ├── Domain/ # Entities, Value Objects, Events
│ │ │ ├── Application/ # Commands, Queries, Handlers
│ │ │ └── Ports/ # Interfaces (driven/driving)
│ │ ├── Ordering.Infrastructure/ # External dependencies
│ │ │ ├── Persistence/ # EF Core, DbContext
│ │ │ └── Adapters/ # External service implementations
│ │ └── Ordering.DataTransfer/ # DTOs for module-to-module communication
│ ├── Inventory/
│ │ ├── Inventory.Core/
│ │ ├── Inventory.Infrastructure/
│ │ └── Inventory.DataTransfer/
│ └── Shared/ # Truly shared kernel (minimal)
│ └── Shared.Kernel/ # Common value objects, interfaces
└── Host/ # Composition root, startup
└── Api/ # Controllers, middleware
主な原則
- モジュール間でドメインを参照しない - モジュールは、他のモジュールの Core プロジェクトを参照できません
- 通信には DataTransfer を使用する - モジュール間のデータ受け渡しには DTO を使用します
- インフラストラクチャは内部に留める - 各モジュールが独自の永続化を所有します
- 共有カーネルは最小限にする - 真に普遍的な概念のみを Shared に配置します
ポートとアダプター(ヘキサゴナル)パターン
ヘキサゴナルアーキテクチャでは、ポート(インターフェイス)とアダプター(実装)を通じて、ビジネスロジックを外部の関心事から分離します。
詳細ガイド: references/ports-adapters-guide.md を参照してください
クイックリファレンス
┌─────────────────────────────────────────────────────────────┐
│ DRIVING SIDE (Primary) │
│ Controllers, CLI, Message Handlers, Tests │
│ │ │
│ ┌──────▼──────┐ │
│ │ PORTS │ (Input interfaces) │
│ │ IOrderService│ │
│ └──────┬──────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ APPLICATION │ │
│ │ (Use Cases/Handlers) │ │
│ └────────────┬────────────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ DOMAIN │ │
│ │ (Entities, Value Objs) │ │
│ └────────────┬────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ PORTS │ (Output interfaces) │
│ │IOrderRepository│ │
│ └──────┬──────┘ │
│ │ │
│ DRIVEN SIDE (Secondary) │
│ Databases, External APIs, File Systems, Queues │
└─────────────────────────────────────────────────────────────┘
駆動ポート: アプリケーションが公開するインターフェイス(アプリケーションが実装) 被駆動ポート: アプリケーションが必要とするインターフェイス(アダプターが実装)
モジュール間通信
モジュールは密結合を生じさせずに通信する必要があります。主なパターンは 2 つあります。
詳細ガイド: references/module-communication.md を参照してください
同期通信(DataTransfer)
即時応答が必要なクエリ操作の場合:
// In Inventory module - needs to check product availability
public class CheckStockHandler
{
private readonly IOrderingModuleApi _orderingApi;
public async Task<StockStatus> Handle(CheckStockQuery query)
{
// Get order info through DataTransfer DTO
var orderDto = await _orderingApi.GetOrderSummary(query.OrderId);
// orderDto is from Ordering.DataTransfer project
}
}
非同期通信(MediatR ドメインイベント)
他のモジュールが反応する必要のある状態変更の場合:
// In Ordering module - publishes event after order is placed
public class PlaceOrderHandler
{
private readonly IMediator _mediator;
public async Task Handle(PlaceOrderCommand command)
{
// ... create order ...
// Publish integration event (handled by other modules)
await _mediator.Publish(new OrderPlacedIntegrationEvent(
order.Id, order.Items.Select(i => i.ProductId)));
}
}
// In Inventory module - handles the event
public class OrderPlacedHandler : INotificationHandler<OrderPlacedIntegrationEvent>
{
public async Task Handle(OrderPlacedIntegrationEvent notification, CancellationToken ct)
{
// Reserve inventory for the order
await _inventoryService.ReserveStock(notification.ProductIds);
}
}
データ分離パターン
データベースレベルでの密結合を防ぐため、各モジュールは独自のデータを所有する必要があります。
詳細ガイド: references/data-patterns.md を参照してください
モジュールごとに DbContext を分離
// Ordering module's DbContext
public class OrderingDbContext : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
// Only configure Ordering entities
builder.ApplyConfigurationsFromAssembly(typeof(OrderingDbContext).Assembly);
}
}
// Inventory module's DbContext
public class InventoryDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<StockLevel> StockLevels { get; set; }
}
主なルール
- モジュール間で外部キーを使用しない - 代わりに ID を値オブジェクトとして使用します
- テーブルを共有しない - 各モジュールが自身のテーブルを完全に所有します
- 同じデータベースの使用は許容される - モジュールごとにスキーマまたはプレフィックスを分けます
- 結果整合性を許容する - モジュール間のデータが古くなる場合があることを受け入れます
MediatR の統合
MediatR は、モジュール内の CQRS とモジュール間の統合イベントの両方にメッセージング基盤を提供します。
詳細ガイド: references/mediatr-integration.md を参照してください
登録パターン
// In each module's registration
public static class OrderingModule
{
public static IServiceCollection AddOrderingModule(this IServiceCollection services)
{
services.AddMediatR(cfg =>
cfg.RegisterServicesFromAssembly(typeof(OrderingModule).Assembly));
services.AddScoped<IOrderingModuleApi, OrderingModuleApi>();
services.AddDbContext<OrderingDbContext>();
return services;
}
}
イベントの種類
| 種類 | 範囲 | 使用例 |
|---|---|---|
| ドメインイベント | モジュール内 | 集約の状態変更 |
| 統合イベント | モジュール間 | 変更を他のモジュールに通知する |
イベントストーミングとの統合
このスキルは、境界づけられたコンテキストの発見において event-storming スキルと連携します。
- イベントストーミングで境界づけられたコンテキストとイベントを発見する
- モジュラーアーキテクチャで、それらのコンテキストをモジュールとして実装する
- イベントを MediatR の統合イベントにする
- コンテキストの境界をモジュール境界にする
ワークフロー:
Event Storming (discover "what")
↓
Bounded Contexts identified
↓
Modular Architecture (implement "where")
↓
Module structure created
↓
Fitness Functions (enforce boundaries)
フィットネス関数
モジュール境界を強制するには、fitness-functions スキルを使用します。
- モジュール間でドメインを参照しない
- DataTransfer プロジェクトのルール(DTO のみ)
- インフラストラクチャの分離(実装を漏洩させない)
クイックスタートチェックリスト
新しいモジュラーモノリスを開始する際は、次の手順に従います。
- Modules/ ディレクトリ構造を作成する
- 最小限の共有型を含む Shared.Kernel を定義する
- モジュールごとにプロジェクト(Core、Infrastructure、DataTransfer)を作成する
- モジュールごとに個別の DbContext を設定する
- ドメインイベント/統合イベント用に MediatR をセットアップする
- 境界を強制するアーキテクチャテストを追加する
- DataTransfer プロジェクトにモジュール API を文書化する
参考資料
references/ports-adapters-guide.md- ヘキサゴナルアーキテクチャのパターンの詳細references/module-communication.md- 同期および非同期の通信パターンreferences/data-patterns.md- データベース分離の戦略references/mediatr-integration.md- MediatR の設定とパターン
バージョン履歴
- v1.0.0(2025-12-22):初回リリース
- モジュール構造のパターン
- ポートとアダプターの概要
- モジュール間通信(同期/非同期)
- データ分離のパターン
- MediatR の統合
- イベントストーミングの統合
最終更新
日付: 2025-12-22 モデル: claude-opus-4-5-20251101