| name | packaging-design |
| description | 乱雑なコードベースを、明確なパッケージ/モジュール構造に再設計するための指針。対象は (1) 乱雑なコードの再整理、(2) 単一巨大モジュールの分割、(3) パッケージ境界のレビュー、(4) 新規プロジェクトのモジュール階層設計。 |
パッケージ設計スキル
乱雑なコードを、体系立てた分析で整理されたパッケージへ再構成する。
コアワークフロー
フェーズ1: Chunk Down(分解) - 責務を洗い出す
対象コードから原子的な責務を抽出する:
- 公開されている型・関数・トレイトをすべて列挙する
- 各要素に対して「一文の責務説明」を書く
- 暗黙的な責務(エラー処理、ログ、設定など)を洗い出す
- 複数責務を持つ要素(SRP違反)をフラグする
出力: 10〜50件の原子的な責務一覧
フェーズ2: MECE Grouping - 候補パッケージを作る
MECE(重複なし・漏れなし)で責務を分割する:
- Mutually Exclusive: 各責務は1つのグループにのみ属する
- Collectively Exhaustive: すべての責務が割り当て済みである
グルーピングのヒューリスティクス:
- 一緒に変更される要素 → 同一パッケージ(CCP)
- 一緒に再利用される要素 → 同一パッケージ(CRP)
- ドメイン概念の境界 → 自然なパッケージ境界
出力: 3〜7個の候補パッケージ(境界が明確なもの)
フェーズ3: Chunk Up - 抽象化と命名
各グループを一段抽象化して命名する:
- 各グループを貫く概念を見つける
- 技術的な役割ではなく、ドメイン概念で命名する
- そのパッケージの目的を一文で言えることを確認する
- 命名が難しい場合はグルーピングが誤っている可能性が高い → フェーズ2に戻る
良い例: authentication, billing, inventory
避ける例: utils, helpers, common, misc
フェーズ4: 原則で検証する
提案した構造が設計原則を満たしているか確認する:
| 原則 | 確認観点 |
|---|---|
| 高凝集 | パッケージ内の要素が単一目的に収束しているか |
| 低結合 | パッケージ間の依存が最小か |
| ADP | 循環依存がないか |
| SDP | 依存が安定側に向かっているか |
詳細は references/principles.md を参照。
フェーズ5: 公開インターフェースを定義する
各パッケージについて:
pubにすべき要素(外部契約)を特定する- それ以外は
pub(crate)か private にする - インターフェースが複雑ならファサード型/関数を用意する
- モジュールドキュメントで契約を説明する
Rust固有のパターン
references/rust-patterns.md を参照:
mod階層設計- ワークスペースと単一クレートの選択
- featureフラグ戦略
- 再エクスポートの指針
※ このプロジェクトでは mod.rs を使わない。2018モジュール方式で package_name.rs と package_name/ 配下のファイルで構成する。
アンチパターン
- God module: 1ファイルに500行以上の責務が集中している
- 循環依存: A → B → C → A
- 不安定依存: 中核モジュールが変化の激しいモジュールに依存
- 抽象の漏れ: 内部型が公開APIに漏れ出る
- 雑多な util/common: 関連性の低い要素が「その他」で集約される
出力フォーマット
再構成提案は以下の形式で示す:
## 提案パッケージ構成
package_name.rs (目的: 1文で説明)
package_name/
├── submodule_a.rs
└── submodule_b.rs
### 依存関係
package_a → package_b (reason)
### 移行手順
1. 新しいモジュール構造を作成する
2. 型や関数を最小変更で移動する
3. import を更新する
4. テストが通ることを確認する