domain-model-boundaries-mapper について
ドメイン駆動設計でドメイン境界と責務を整理する開発スキルです。コンテキストマップ、依存関係、インターフェース契約、移行案を通じて、システムの設計やリファクタリングを支援します。
主な機能
- 01境界づけられたコンテキストとコアドメインの特定
- 02コンテキストと依存関係のマッピング
- 03インターフェース契約とイベントの定義
- 04腐敗防止層とリファクタリング案の設計
- 05段階的な移行計画の作成
活用シーン
- 01既存コードのドメイン境界の整理
- 02サービス間の密結合の軽減
- 03共有モデルや肥大化したサービスの分割
- 04コンテキストの分離とサービス抽出の計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ patricio0312rev/ skills --skill domain-model-boundaries-mapperインストール後、Claude Code で/domain-model-boundaries-mapperを入力して読み込まれたか確認します。
詳細
ドメインモデルと境界のマッピング
ドメイン駆動設計を使用して、ドメインの境界と所有権をマッピングします。
ドメインマップのテンプレート
# Domain Map: E-Commerce Platform
## Bounded Contexts
### 1. Customer Management
**Core Domain:** User accounts, profiles, preferences
**Owner:** Customer Team
**Ubiquitous Language:**
- Customer: Registered user with account
- Profile: Customer personal information
- Preferences: User settings and choices
**Entities:**
- Customer (id, email, name)
- Address (id, customer_id, street, city)
- PaymentMethod (id, customer_id, type, token)
**Bounded Context Diagram:**
┌─────────────────────────────┐ │ 顧客管理 │ │ ┌─────────┐ ┌──────────┐ │ │ │顧客 │ │ 住所 │ │ │ └─────────┘ └──────────┘ │ │ ┌─────────────────────┐ │ │ │ 支払い方法 │ │ │ └─────────────────────┘ │ └─────────────────────────────┘
### 2. Order Management
**Core Domain:** Order processing, fulfillment
**Owner:** Orders Team
**Ubiquitous Language:**
- Order: Purchase request with line items
- LineItem: Product quantity in order
- Fulfillment: Physical delivery of order
**Entities:**
- Order (id, customer_id, status, total)
- LineItem (id, order_id, product_id, quantity)
- Shipment (id, order_id, tracking_number)
### 3. Product Catalog
**Core Domain:** Product information, inventory
**Owner:** Catalog Team
**Ubiquitous Language:**
- Product: Sellable item
- SKU: Stock keeping unit
- Inventory: Available stock
**Entities:**
- Product (id, name, price, description)
- Inventory (sku, quantity, warehouse_id)
## Context Relationships
顧客管理 ──────▶ 注文管理 (customer_id)
商品カタログ ──────▶ 注文管理 (product_id)
注文管理 ──────▶ フルフィルメント (order events)
## Anti-Corruption Layers
### Order Management → Customer Management
**Problem:** Orders need customer data but shouldn't depend on Customer domain model
**Solution:** Customer Adapter
```typescript
// Order domain's view of customer
interface CustomerForOrder {
id: string;
shippingAddress: Address;
billingAddress: Address;
}
// Adapter translates Customer domain to Order domain
class CustomerAdapter {
async getCustomerForOrder(customerId: string): Promise<CustomerForOrder> {
const customer = await customerService.getCustomer(customerId);
return {
id: customer.id,
shippingAddress: this.toOrderAddress(customer.defaultShippingAddress),
billingAddress: this.toOrderAddress(customer.defaultBillingAddress),
};
}
}
依存関係マップ
┌──────────────┐
│ Customer │
└──────┬───────┘
│
▼
┌──────────────┐ ┌────────────┐
│ Orders │─────▶│ Products │
└──────┬───────┘ └────────────┘
│
▼
┌──────────────┐
│ Fulfillment │
└──────────────┘
依存関係のルール:
- 顧客には依存関係がありません
- 注文は顧客(読み取り)と商品(読み取り)に依存します
- フルフィルメントは注文(イベント)に依存します
インターフェース契約
顧客管理 → 注文
// Public interface exposed by Customer domain
interface CustomerService {
getCustomer(id: string): Promise<Customer>;
getCustomerAddresses(id: string): Promise<Address[]>;
}
// Events published
interface CustomerUpdated {
customerId: string;
email: string;
name: string;
}
商品カタログ → 注文
interface ProductService {
getProduct(id: string): Promise<Product>;
checkAvailability(sku: string, quantity: number): Promise<boolean>;
reserveInventory(items: ReservationRequest[]): Promise<Reservation>;
}
リファクタリングの推奨事項
問題 1:密結合
現状: 注文が顧客データベースに直接クエリを実行しています 問題: 境界づけられたコンテキストに違反し、結合を生み出します 推奨事項: 代わりに顧客 API を使用します
// ❌ Before: Direct database access
const customer = await db.customers.findById(customerId);
// ✅ After: API call through adapter
const customer = await customerAdapter.getCustomerForOrder(customerId);
問題 2:共有モデル
現状: 同じ User モデルを複数のコンテキストで使用しています
問題: あるコンテキストでの変更が、ほかのコンテキストに影響します
推奨事項: コンテキストごとにモデルを分離します
// Customer context
interface Customer {
id: string;
email: string;
profile: CustomerProfile;
preferences: CustomerPreferences;
}
// Order context (different model!)
interface OrderCustomer {
id: string;
shippingAddress: Address;
billingAddress: Address;
}
問題 3:万能サービス
現状: OrderService が注文、在庫、支払い、配送を処理しています
問題: 1 つのサービスが多くの責務を担いすぎています
推奨事項: 境界づけられたコンテキストを切り出します
- OrderService:注文のライフサイクル
- InventoryService:在庫管理
- PaymentService:支払い処理
- FulfillmentService:配送
戦略的設計パターン
パターン 1:共有カーネル
使用する場面: 2 つのコンテキストで一部のコードを共有する必要がある場合 例: 共通の値オブジェクト(Money、Address)
// Shared kernel (minimal!)
class Money {
constructor(public amount: number, public currency: string) {}
}
パターン 2:顧客/サプライヤー
使用する場面: あるコンテキストが別のコンテキストに依存する場合 例: 注文(顧客)が商品(サプライヤー)に依存する
- サプライヤーがインターフェースを定義します
- 顧客は自分たちのニーズに合わせて適応します
パターン 3:公開された言語
使用する場面: 多くのコンテキストで同じデータが必要な場合 例: 商品イベント
interface ProductCreated {
productId: string;
name: string;
price: Money;
publishedAt: Date;
}
移行戦略
フェーズ 1:境界を特定する
- 既存のコードをドメインにマッピングする
- 結合箇所を特定する
- 依存関係を文書化する
フェーズ 2:インターフェースを定義する
- コンテキスト間の API を設計する
- アダプターレイヤーを作成する
- イベント契約を定義する
フェーズ 3:疎結合にする
- データベースへの直接アクセスを API に置き換える
- 腐敗防止層を導入する
- コンテキストごとにモデルを分離する
フェーズ 4:サービスを切り出す(任意)
- コンテキストを個別のサービスに移行する
- API ゲートウェイを実装する
- イベントバスをセットアップする
ベストプラクティス
- ユビキタス言語:コードとドメインで同じ用語を使用する
- 境界づけられたコンテキスト:明確な境界を設け、モデルを分離する
- コンテキストマップ:関係を文書化する
- 腐敗防止層:ドメインの整合性を保護する
- イベント駆動:イベントを介して疎結合にする
- データベースの分離:各コンテキストが自身のデータを所有する
出力チェックリスト
- 境界づけられたコンテキストを特定済み(3~7 個)
- コアドメインとサポートドメイン
- コンテキストごとにユビキタス言語を定義済み
- エンティティ/集約の定義
- コンテキスト関係図
- 依存関係マップ
- インターフェース契約を定義済み
- 腐敗防止層を設計済み
- リファクタリングの推奨事項
- 移行戦略