package-design

乱雑なコードベースを、明確なパッケージ/モジュール構造に再設計するための指針。 対象は (1) 乱雑なコードの再整理、(2) 単一巨大モジュールの分割、 (3) パッケージ境界のレビュー、(4) 新規プロジェクトのモジュール階層設計。 トリガー:「パッケージ構造を見直したい」「モジュールの依存関係が複雑」 「ファイル配置を整理したい」「循環依存を解消したい」といった構造改善リクエストで起動。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "package-design" with this command: npx skills add j5ik2o/okite-ai/j5ik2o-okite-ai-package-design

パッケージ設計スキル

乱雑なコードを、体系立てた分析で整理されたパッケージへ再構成する。

核心: パッケージ設計は「ソースコードの配置」ではなく「変更の波をどこで止めるか」「依存の向きをどう制御するか」の設計問題である。

コアワークフロー

フェーズ1: 変更理由の分析 - 分割の起点を見つける

分割の出発点は「処理手順」ではなく「変化しそうな設計決定」である。

Parnas の情報隠蔽に基づき、まず以下を問う:

  • 「何が変わるか?」(変更理由・変更源の列挙)
  • 「変わったとき、どこまでを巻き込んでよいか?」(リリース単位・責務境界)
  1. 対象コードの変更履歴(git log)を分析し、一緒に変更されるファイル群を特定する
  2. 外部要因(UI変更、DB変更、API変更、ビジネスルール変更)ごとに影響範囲を整理する
  3. 各変更理由に対して「この変更は、ここで閉じるべき」という境界候補を仮置きする

出力: 変更理由と影響範囲の対応表

フェーズ2: Chunk Down(分解) - 責務を洗い出す

対象コードから原子的な責務を抽出する:

  1. 公開されている型・関数・トレイトをすべて列挙する
  2. 各要素に対して「一文の責務説明」を書く
  3. 暗黙的な責務(エラー処理、ログ、設定など)を洗い出す
  4. 複数責務を持つ要素(SRP違反)をフラグする

出力: 10〜50件の原子的な責務一覧

フェーズ3: グルーピング - 候補パッケージを作る

責務を分割する際の軸を選択し、グルーピングする。

分割軸の選択

分割軸凝集の性質適するケースリスク
機能(feature/vertical)変更が縦に閉じるチーム独立、マイクロサービス候補共通化地獄
ドメイン(業務概念)情報的凝集ドメインモデルの一貫性重視コンテキスト間翻訳コスト
レイヤ(技術層)技術責務の分離小規模、導入初期1変更が全層に散る
責務(変更理由)CCP準拠変更頻度が明確初期分析コスト
API境界(公開IF)表面積最小化ライブラリ設計内部柔軟性とのバランス

グルーピングのヒューリスティクス

  • 一緒に変更される要素 → 同一パッケージ(CCP)
  • 一緒に再利用される要素 → 同一パッケージ(CRP)
  • ドメイン概念の境界 → 自然なパッケージ境界

出力: 3〜7個の候補パッケージ(認知負荷の観点から7±2が目安)

MECEによる検証(設計目標ではなくチェック観点として)

MECEは「設計の目的」ではなく「網羅性チェックの補助」として使う。 厳密MECEにこだわりすぎると、横断的関心(ログ、認可、トランザクション等)の扱いで境界が薄くなる危険がある。8〜9割の網羅で十分。

  • 各責務は1つのパッケージに割り当てられているか(重複なし)
  • 未割り当ての責務が残っていないか(漏れなし)
  • 「Xはどこに置く?」に対して答えが1つだけあるか

詳細は references/principles.md#mece-分割 を参照。

フェーズ4: Chunk Up - 抽象化と命名

各グループを一段抽象化して命名する:

  1. 各グループを貫く概念を見つける
  2. 技術的な役割ではなく、ドメイン概念で命名する
  3. そのパッケージの目的を一文で言えることを確認する
  4. 命名が難しい場合はグルーピングが誤っている可能性が高い → フェーズ3に戻る

良い例: authentication, billing, inventory 避ける例: utils, helpers, common, misc

フェーズ5: 依存関係設計と原則検証

依存の向きを設計する

依存は「より安定・より抽象」な側へ向ける。

  1. パッケージ間の依存グラフを描く
  2. 循環依存がないか確認(ADP)
  3. 安定側(多くから依存される)→ 不安定側(多くに依存する)の向きに依存が逆転していないか確認(SDP)
  4. 安定なパッケージが十分抽象的か確認(SAP)

循環依存の解消手順

循環が見つかった場合:

  1. 依存性逆転: 依存される側の抽象(Interface/Trait)を依存する側へ移し、実装は逆向きに差し込む
  2. 共有抽出: 相互参照している共通型/ロジックを第三のパッケージへ移動し、循環辺を切る
  3. 統合: 本当に同一責務ならパッケージを統合する

原則チェック

原則確認観点
高凝集パッケージ内の要素が単一目的に収束しているか
低結合パッケージ間の依存が最小か
ADP循環依存がないか
SDP依存が安定側に向かっているか
SAP安定なパッケージが十分抽象的か
CCP同じ変更理由のものが同一パッケージに閉じているか

詳細は references/principles.md を参照。

フェーズ6: 公開インターフェースとテスト境界の定義

公開インターフェース

各パッケージについて:

  1. pub にすべき要素(外部契約)を特定する
  2. それ以外は pub(crate) か private にする
  3. インターフェースが複雑ならファサード型/関数を用意する
  4. モジュールドキュメントで契約を説明する

テスト境界の対応付け

テストを「境界」に対応させる:

テスト種別対象目的
ユニットテストパッケージ内部内部の凝集を守る
統合テストパッケージ間境界横断の依存が設計どおりか
契約テスト公開API境界互換性(結合点)を守る

評価チェックリスト

提案した構造が以下を満たしているか確認する(Yesが多いほど高凝集・低結合):

  • 各パッケージの目的が一文で言える(何を提供し、何を隠すか)
  • 境界を越える依存は、公開API(ファサード/ポート)を経由している
  • パッケージ依存グラフが非循環である
  • 安定度の高い領域が十分抽象化されている
  • 変更理由がパッケージ境界で止まる
  • 境界のテストが公開APIの範囲と一致している

メトリクスによる定量評価

メトリクス対象意味
Ca(求心結合)パッケージ外部から依存される数
Ce(遠心結合)パッケージ外部へ依存する数
I = Ce/(Ca+Ce)パッケージ不安定性(0=最安定, 1=最不安定)
D(Main Sequenceからの距離)パッケージA + I = 1 からの乖離

詳細は references/principles.md#パッケージメトリクス を参照。

リファクタリングトリガー

以下が観測されたら分割/境界の見直しを検討する:

  • 変更が複数パッケージに散る(CCP違反の兆候)
  • Ce増大(外部依存が増え続ける)
  • パッケージサイクル(循環依存)が発生する
  • パッケージ内の複雑度が上昇し続ける

Rust固有のパターン

references/rust-patterns.md を参照:

  • mod 階層設計
  • ワークスペースと単一クレートの選択
  • featureフラグ戦略
  • 再エクスポートの指針

※ このプロジェクトでは mod.rs を使わない。2018モジュール方式で package_name.rspackage_name/ 配下のファイルで構成する。

代表パターン比較

パターン凝集軸利点リスク
レイヤード技術責務導入容易1変更が全層に散る
機能別(vertical slicing)ユースケース変更が閉じやすい共通化地獄
コンポーネント別機能集合境界が明確公開API設計コスト
Bounded Contextドメイン境界モデル整合性コンテキスト間翻訳コスト
Ports & Adapters / Clean依存方向テスト容易構造の形式主義

アンチパターン

  • God module: 1ファイルに500行以上の責務が集中している
  • 循環依存: A → B → C → A(境界が実質的に崩壊したシグナル)
  • 不安定依存: 中核モジュールが変化の激しいモジュールに依存(SDP違反)
  • 抽象の漏れ: 内部型が公開APIに漏れ出る
  • 雑多な util/common: 関連性の低い要素が「その他」で集約される(共通結合の温床)
  • レイヤだけで境界なし: 見た目がレイヤでも相互参照や内部参照が放置されている
  • cargo cult パッケージング: パターンを理由理解なしに適用し、構造は整って見えるが意図が失われている

出力フォーマット

再構成提案は以下の形式で示す:

## 提案パッケージ構成

package_name.rs (目的: 1文で説明)
package_name/
├── submodule_a.rs
└── submodule_b.rs

### 依存関係
package_a → package_b (reason)

### メトリクス概算
package_a: Ca=3, Ce=1, I=0.25 (安定)
package_b: Ca=1, Ce=2, I=0.67 (不安定)

### 移行手順
1. 新しいモジュール構造を作成する
2. 型や関数を最小変更で移動する
3. import を更新する
4. テストが通ることを確認する
5. 循環依存がないことを静的解析で確認する

関連スキル(併読推奨)

このスキルを使用する際は、以下のスキルも併せて参照すること:

  • ddd-module-pattern: DDD文脈でのドメイン語彙ベースのモジュール設計
  • refactoring-packages: 既存パッケージ構造のリファクタリング実行
  • clean-architecture: パッケージ設計の基盤となる4層アーキテクチャ

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

domain-model-extractor

No summary provided by upstream source.

Repository SourceNeeds Review
General

cross-aggregate-constraints

No summary provided by upstream source.

Repository SourceNeeds Review
General

tell-dont-ask

No summary provided by upstream source.

Repository SourceNeeds Review
General

repository-design

No summary provided by upstream source.

Repository SourceNeeds Review
package-design | V50.AI