はじめに

Pythonプロジェクトにおけるモジュール分割の失敗は、読みやすさ・保守性・再利用性に致命的な影響を与える。
レビューアーの役割は、単に「ファイルサイズが大きい」「関数が多すぎる」といった表面的な指摘ではなく、
構造的・設計的な問題としてモジュール分割の機能不全を見抜くことにある。

典型的な失敗パターンには、次のような構造が含まれる:

  • utils.pycommon.pyへの過剰な集約
  • 明確な責務を持たない「なんでも屋」的モジュール構成
  • テストが困難なほど依存関係が複雑
  • ドメイン境界や変更単位を無視した機能グルーピング

なぜモジュール分割は失敗するのか

1. 追加され続ける便利関数

# utils.py

def slugify(text): ...
def parse_date(value): ...
def get_user_timezone(): ...
def connect_to_api(): ...
def retry_on_failure(fn): ...

開発の初期段階では「一時的に使いたい」目的で配置された関数が、次第に恒常化し、何でも入っている不可視のブラックボックスと化す。

Comment
@Reviewer: `utils.py`には用途もドメインも異なる関数が無秩序に集まっています。実行コンテキスト(API接続、日付処理、UI補助など)ごとに分離すべきです。

2. 「再利用したい」が分割の基準になっている

  • 関数を「再利用できそう」という観点だけで他の場所から移動
  • 実際にはその関数の依存関係(設定、型、例外、状態)が明確に分離されておらず、意図と整合していない

モジュール設計に必要な分割基準

❶ 「責務」による分割

関数やクラスが「何のためにあるのか」が明確な単位でモジュールを分ける。
例:API通信/形式変換/通知送信/セッション制御/認証

❷ 「変更の単位」による分割

変更が入るたびに複数箇所に影響が及ぶなら、設計上の結合が強すぎる
責務単位ではなく変更単位で切るのも有効。

❸ 「依存方向」による分割

上位モジュール(ドメイン処理) → 下位モジュール(ユーティリティ)への一方向依存にすべき。
双方向参照や循環importが発生しているなら、構造設計に問題がある。

分割前後の構造比較(PlantUML)

UML Diagram
UML Diagram

よくあるレビュー指摘とチェック観点

構造・症状 指摘すべき観点 レビュー方針の例
1ファイル500行以上で関数多数 モジュールに複数の責務が混在していないか? 責務単位・変更頻度単位で分割を検討
utils.pyが依存対象として全ファイルに存在 utilsがモノリス化・逆方向依存になっていないか? 依存方向の見直しと限定的importの提案
名前が抽象的なcore.py, common.py モジュール名から中身が想定できるか? 機能や目的ベースで命名の再設計
from x import *が頻発している モジュール間の結合が強すぎないか? import粒度を関数単位に絞り分離を促す
テストコードが特定モジュールに集中 テストしやすい構造に分離できていないか? 依存排除とMock/Stubの導入でテスト容易化

utilsの責務崩壊を是正するやりとり

# utils.py

def retry_on_failure(fn): ...
def slugify(title): ...
def send_slack_alert(message): ...
def parse_yaml_config(file): ...
Comment
@Reviewer: retry処理、文字列処理、通知送信、設定読込など全ての関数がこの1ファイルに混在しています。将来的な変更の責務分離を考慮すると、それぞれのドメインに属したモジュールに再配置する方が望ましいです。
Comment
@Developer: 該当関数は他でもよく使われており、utilsに集めることで再利用性を高めたつもりでした。
Comment
@Reviewer: 再利用性よりも、意味のある構造を保つことが重要です。再利用はimport設計やパッケージ階層で担保できます。

分割時の設計補助ツール:ルール・分類の導入

プロジェクトによっては、モジュール分割が属人的になりやすい。
以下のような構造分類のガイドラインを設けておくと、レビューでも一貫した判断が可能になる。

  • domain/:ビジネスドメイン(例:注文、会員、支払い)
  • infra/:技術インフラ層(DB接続、APIクライアント、ログ、リトライ)
  • logic/:純粋なデータ処理(集計、変換)
  • adapter/:外部連携層(ファイルI/O、メール、HTTP通信)

レビュー観点として、モジュールがこのいずれかの分類に収まるか? をチェックするだけでも、かなり設計の妥当性を評価できる。

まとめ:レビューアーがモジュール構造で判断すべきこと

モジュール分割は「ファイルを小さくする」ためではなく、「変更・責務・依存を構造的に分ける」ために行う設計である。

レビューアーは次の視点で設計構造を読み取る必要がある:

  • モジュールが複数の異なる責務を抱えていないか?
  • 名前と中身に意味的乖離がないか?
  • ドメインや実行環境ごとに、構造が分離されているか?
  • 変更頻度と責務の粒度が一致しているか?

モジュールはコードの「整理箱」ではなく、設計思想の「境界線」である。
レビューアーはこの境界が明確かどうかを読み取り、改善を促す立場であるべきだ。