efoo-team/skills

module-boundary-design

機能境界・責務分離・モジュール分割・抽象化の設計判断を行うスキル。どこで境界を切るか、責務をどう分けるか、抽象化が妥当か、責務?

First seen Apr 1, 2026

Installation

$ npx skills add efoo-team/skills --skill module-boundary-design

Summary

機能境界・責務分離・モジュール分割・抽象化の設計判断を行うスキル。どこで境界を切るか、責務をどう分けるか、抽象化が妥当か、責務配置を見直したいときに使用する。単純な CRUD 追加・差分レビュー・API 表面設計には使わない。リファクタリング全般の判断は refactor-mindset…

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from efoo-team/skills · top by installs.

npx skills add efoo-team/skills

Browse all from efoo-team/skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Default branch main
Open issues 4
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

More metadata
tags
["design","architecture","ddd","refactoring"]

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 12,026 B
  • docs SUMMARY.md 496 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 58 installs

SKILL.md

モジュール境界設計スキル

機能の境界をどこに引き、何を同じ側に置き、何を分けるかを判断するための思考手順。


原則

機能境界は 処理の順序 ではなく 変更理由の独立性 で決まる。

そしてもう一つ。境界を「引く」だけでは不十分で、その境界を「成立させる」必要がある。責務を分けただけでは境界にはならない。境界が意味を持つのは、公開面・状態の所有・依存方向・不変条件の守備範囲が明確になったときである。


適用範囲

このスキルを使う場面

  • 機能の境界が曖昧で、どこで切るべきか判断が必要なとき
  • モジュールやクラスが肥大化していて分割を検討するとき
  • 変更の影響が広範囲に波及している構造を改善するとき
  • 抽象化の妥当性に疑いがあるとき
  • 既存の責務配置を見直すとき

このスキルの対象外

  • 単純な CRUD の実装判断
  • 差分レベルのコードレビュー
  • API のインターフェース設計(境界は決まっていて表面だけ考える場合)
  • 依存方向の違反検出だけが目的の場合

思考手順

Step 1: 機能文の構造化

設計対象の機能を「〈主語〉が〈対象〉を〈操作〉する」の形に分解する。複数の操作が含まれていれば、操作ごとに分けて書き出す。

ユーザーが使った言葉をそのまま使わない。「何を受け取り、何を保全し、何を変換し、何を出力するか」という責務が見える動詞に置き換える。


Step 2: 境界候補の発見

以下の4つの観点から、境界の候補を洗い出す。どれか1つではなく、4つすべてを順に確認する。

2-A: 対象の置換(共通性・可変性の識別)

機能文の中の対象(目的語)を、現実的にありうる別の対象で3つ以上置き換える。

  • どの置換でも処理が変わらない部分 → 共通層(抽象化してよい)
  • 置換すると処理の内容・ルール・制約が変わる部分 → 専用層(ドメイン固有に残す)

3つ以上なのは、2つでは偶然の一致と本質的な共通性の区別がつかないため。ただし3つ目が現実に存在しない場合は、無理に一般化せず継ぎ目だけを意識する。

2-B: 意味の分裂の検出

同じ言葉(名詞)が、文脈によって異なる意味で使われていないかを確認する。

同じ「ユーザー」でも、認証では「認証主体」、課金では「支払者」、サポートでは「問い合わせ者」を意味するなら、それぞれ別の境界に属する可能性が高い。意味が変わる地点は境界候補になる。

確認方法:

  • 機能文に登場する主要な名詞を列挙する
  • 各名詞の意味が、機能のどの文脈でも同一かを問う
  • 意味がずれる地点があれば、そこに境界候補を置く
  • 境界をまたぐ場合に翻訳(変換層)が必要かを判断する

2-C: 不変条件の特定

「一緒に壊れてはいけないルール」を特定する。あるルール群が1つのトランザクションや1つの整合性制約で結びついているなら、それらは同じ境界に留めるべき可能性が高い。

確認方法:

  • この機能が守るべきビジネスルール・整合性制約は何かを列挙する
  • そのルールが成立するために、どのデータが同時に参照・更新される必要があるかを特定する
  • 同じ不変条件に縛られるデータと処理は、同じ境界に置く

不変条件が境界をまたぐ場合、調整コスト(saga、eventual consistency、手動整合)が発生する。そのコストを許容できるかどうかが、境界を分けるかどうかの判断材料になる。

2-D: 所有と変更頻度の確認

誰が、どのくらいの頻度で、その部分を変更するかを確認する。

  • 変更の起点が異なるもの(法務起点 vs 開発起点 vs 顧客要望起点)は、別の境界候補
  • 変更頻度が極端に異なるもの(年1回変わるルール vs 週次で変わるルール)は、分離した方が安定する
  • 所有者(継続的に面倒を見る人・チーム)が異なるものは、別の境界にした方が実務上強い

所有者が曖昧な境界は、設計がどれだけ綺麗でも時間とともに崩壊する。


Step 3: 変化軸の特定と境界の確定

Step 2 で見つけた境界候補を「なぜ変わるのか」で分類し、最終的な境界を確定する。

  • 「この部分が変わるとき、他のどこが一緒に変わるか?」→ 一緒に変わるものは同じ境界
  • 「この部分が変わるとき、他はそのままでいられるか?」→ いられるなら、そこが境界

変化軸が異なるものは、見た目が似ていても・処理フロー上は隣接していても分ける。変化軸が同じものは、処理フロー上は離れていても束ねる。


Step 4: 差分の吸収方法の選択

境界内の可変部分をどう設計に取り込むかを、差分の性質に応じて選ぶ。

値だけが異なる場合(型・構造は同一): パラメータ化する。

振る舞い・アルゴリズムが異なる場合: インターフェースを抽出し、実装を差し替え可能にする。

処理の流れ自体が異なる場合: 別のモジュール・サービスとして独立させる。

判断の閾値:

  • パラメータが3つ以下で条件分岐が増えない → パラメータ化してよい
  • パラメータに応じて内部の制御フローが変わる → インターフェース抽出を検討
  • 統合後に型チェックや条件分岐が増えた → 抽象を解体して戻す

Step 5: 境界の成立条件の確認

境界を引いたら、その境界が実際に機能するかを確認する。境界が成立するには、以下の4つが明確である必要がある。

公開面(Public Contract): この境界が外部に提供するインターフェースは何か。何を受け取り、何を返すか。公開面が言語化できないなら、境界が不明確である。

状態の所有: この境界が排他的に所有するデータは何か。他の境界が直接読み書きしてよいデータはあるか。共有される可変状態があるなら、境界は名目上のものでしかない。

依存方向: この境界は何に依存し、何がこの境界に依存するか。循環依存があれば、境界の引き方を見直す。

通信方式: 境界間はどう連携するか。直接呼び出し、イベント、非同期メッセージ、変換層のどれが適切かは、境界の独立性の要求水準で決まる。


Step 6: 変更マトリクスによる検証

想定される変更シナリオを5つ程度並べ、各シナリオで影響を受けるモジュールを特定する。影響が1〜2モジュールに閉じていれば妥当。3モジュール以上に波及するなら、境界の引き直しを検討する。


Step 7: 抽象化の範囲の制限

抽象化は「広げること」だけでなく「受け入れる可変性を制限すること」でもある。

  • 初期実装では今ある具体例だけで動くものを作る
  • インターフェースは切っておくが実装は1つだけにする
  • 2つ目・3つ目の具体的な要件が現れた時点で、必要な分だけ一般化する

まだ存在しない要件のために抽象化すると、必要な柔軟性ではなく不要な複雑性が生まれる。間違った抽象を共有するより、重複を許容する方がコストが低い。


重要な区別: 境界設計と内部構造は別の問題

設計相談では、以下が頻繁に混同される。

  • 境界設計: どの責務をどのモジュールに配置するか。意味・変化軸・不変条件・所有で決める
  • 内部構造: 境界の中をどう整理するか。vertical slice、layer、CQRS などは内部戦略

この2つは別の問題であり、別の判断基準で決める。「feature ごとに切るべきか、domain ごとに切るべきか」という問いが出たら、まず「それは境界の話か、内部構造の話か」を切り分ける。


命名の原則

責務名で命名する。実装技術名で命名しない。 名前が「何の技術を使っているか」を説明しているなら実装名であり、悪い兆候。名前が「何の責任を負っているか」を説明しているなら責務名であり、良い兆候。

1つの名前に複数の責務が含まれていないか検査する。 And / Or / Manager / Handler / Processor のような汎用語は、複数の変化軸が1つに混ざっている可能性を示す。


反パターン

以下は境界・責務配置の観点で扱う。リファクタリングを「いつ・どの規模で実施するか」の判断は refactor-mindset の担当。

1. フロー順分割

処理フローの順番(Step1, Step2, Step3)でモジュールを切る。変化軸をまたぐ境界になりやすい。

2. 間違った抽象の共有

共通化した結果、対象種別ごとの条件分岐・パラメータ・例外ケースが増殖する。統合前より複雑になったら、抽象を解体して重複に戻す。

3. 全能サービス

XxxManager, XxxHandler, XxxProcessor に責務が集中する。検出したら、そこに含まれる責務を列挙し、変化軸ごとに分離候補を出す。

4. 貧血ドメインモデル

データだけがエンティティにあり、ロジックがすべてサービスにある。境界内の責務配置が崩れているサイン。データとそのデータに対する操作が別の場所に散っている場合、それらを同じ場所に寄せることを検討する。

5. 名詞の類似性による統合

名前が似ているという理由だけで処理を統合する。操作集合・不変条件・エラー境界が一致しない限り、統合は避ける。

6. 過剰な先行抽象

具体例が1つしかないのに汎用フレームワークを作る。「将来必要になるかもしれない」は分割の根拠にならない。

7. 状態の暗黙共有

パッケージやフォルダは分かれているが、可変な状態を複数モジュールが直接読み書きしている。境界は名目上のものでしかなく、実質的に密結合。

8. 肥大化した境界

1つの境界の中に、実際には独立に変化する複数のサブドメインが同居している。境界自体は正しいが、粒度が粗すぎる。分割が必要になったら、最も変更頻度が高く他と独立しているサブドメインから切り出す。


理論的根拠

各ステップ・反パターンの理論的出典(SCV 分析・情報隠蔽・SRP・Bounded Context・Aggregate・Wrong Abstraction・Team Topologies 等)は references/theory.md を参照。