mcpField
P
python-design-patterns

python-design-patterns

github.com/wshobson開発41.9k23.1k 回インストール2 週間前に更新
リポジトリ

python-design-patterns について

Python のコンポーネントやシステムに基本的な設計原則を適用するスキルです。シンプルでモジュール化され、テストや変更がしやすいコードを目指す開発者向けです。

主な機能

  1. 01単一責任の原則を適用
  2. 02継承よりコンポジションを優先
  3. 03三回ルールで抽象化を判断
  4. 04依存性注入でテスト容易性を向上

活用シーン

  1. 01Python コンポーネントの設計
  2. 02複雑なコードのリファクタリング
  3. 03複雑さと結合度の評価
  4. 04モジュール型アーキテクチャの計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wshobson/agents --skill python-design-patterns

インストール後、Claude Code で/python-design-patternsを入力して読み込まれたか確認します。

同梱ファイルreferences/details.md

詳細

Python デザインパターン

基本的な設計原則を用いて、保守しやすい Python コードを記述します。これらのパターンは、理解・テスト・変更が容易なシステムを構築するのに役立ちます。

このスキルを使う場面

  • 新しいコンポーネントやサービスを設計するとき
  • 複雑または絡み合ったコードをリファクタリングするとき
  • 抽象化を作成すべきか判断するとき
  • 継承とコンポジションのどちらを選ぶか決めるとき
  • コードの複雑さと結合度を評価するとき
  • モジュール式のアーキテクチャを計画するとき

中心となる概念

1. KISS (シンプルに保つ)

動作する最もシンプルな解決策を選びます。複雑さは具体的な要件によって正当化されなければなりません。

2. 単一責任 (SRP)

各単位は、変更される理由を 1 つだけ持つべきです。関心事を分離し、焦点を絞ったコンポーネントに分割します。

3. 継承よりコンポジション

クラスを拡張するのではなく、オブジェクトを組み合わせて振る舞いを構築します。

4. 三回ルール

抽象化する前に、3 つの実例が揃うまで待ちます。重複は、早すぎる抽象化よりも多くの場合に優れています。

クイックスタート

# Simple beats clever
# Instead of a factory/registry pattern:
FORMATTERS = {"json": JsonFormatter, "csv": CsvFormatter}

def get_formatter(name: str) -> Formatter:
    return FORMATTERS[name]()

詳細なパターンと実例

詳細なパターンのドキュメントは references/details.md にあります。上記のナビゲーション階層では不十分な場合に、そのファイルを読んでください。

ベストプラクティスのまとめ

  1. シンプルに保つ - 動作する最もシンプルな解決策を選ぶ
  2. 単一責任 - 各単位は変更される理由を 1 つだけ持つ
  3. 関心事を分離する - 明確な目的を持つ独立したレイヤー
  4. 継承ではなくコンポジション - 柔軟性のためにオブジェクトを組み合わせる
  5. 三回ルール - 抽象化する前に待つ
  6. 関数を小さく保つ - 20〜50 行 (複雑さによって変動)、1 つの目的
  7. 依存関係を注入する - テスト容易性のためにコンストラクタインジェクションを使用する
  8. 抽象化する前に削除する - デッドコードを削除してから、パターンを検討する
  9. 各レイヤーをテストする - 各関心事に対して分離したテストを行う
  10. 巧みさより明示性 - 読みやすいコードは洗練されたコードに勝る

トラブルシューティング

クラスが肥大化し、複数の責任を持っているように見えるが、分割すると間違っているように感じる。 「変更される理由」テストを適用します。このクラスを編集する必要が生じる可能性のあるすべての変更を列挙します。そのリストに異なるドメインの項目 (例: HTTP パース AND ビジネスルール AND フォーマット) が含まれている場合は、分割します。すべての変更が同じドメインの関心事に由来する場合、そのクラスは適切なサイズである可能性があります。

すべての依存関係をコンストラクタ経由で注入すると、7 個以上のパラメータを持つコンストラクタが生成される。 これは依存性注入の問題ではなく、1 つのクラスに責任が多すぎる兆候です。まずクラスをより小さな単位に分割すれば、各コンストラクタは自然と小さくなります。

コンポジションが、追跡が難しいほど深くネストしたラッパーオブジェクトを生み出している。 コンポジションは浅く (2〜3 レベル) 保ちます。ラップが唯一の仕組みである場合は、デコレータオブジェクトの連鎖よりも、プロトコルベースのアプローチや単純な関数コンポジションのほうがすっきりするかどうかを検討します。

三回ルールはまだ抽象化するなと言っているが、一方のコピーだけが更新されもう一方が更新されないことで重複がバグを引き起こしている。 危険な形で分岐する重複は、もっと早く抽象化すべきです。三回ルールはヒューリスティックであり、法則ではありません。コピーがすでに誤って分岐している場合は、直ちに抽出し、共有される振る舞いを検証するテストを追加します。

サービスレイヤーが API レイヤーからインポートしており、依存関係の方向が壊れている。 これはレイヤー違反です。サービスレイヤーはハンドラーからインポートしてはなりません。両方がインポートできる共有の型/モデルレイヤーを導入し、依存関係の矢印を下向き (API → Service → Repository) に保ちます。

関連スキル

  • python-testing-patterns — ここで確立した依存性注入の構造を用いて、各レイヤーを分離してテストします
  • python-project-structure — モジュールとディレクトリ構成を整理し、最初からレイヤー境界を明示します

コメント