implementation-design-patterns-python について
モダンなPython 3.10以降を対象に、GoFのデザインパターン22種類を扱うリファレンススキルです。Pythonらしい実装を優先し、適用条件、実行可能な例、トレードオフ、関連パターンを示して不要な抽象化を避けます。
主な機能
- 013カテゴリにわたる22パターン
- 02Pythonらしい実装とサンプルを優先
- 03適用・非適用の判断指針
- 04トレードオフと関連パターンの参照
活用シーン
- 01複雑なオブジェクト構築方法の選択
- 02分岐処理や絡み合ったオブジェクト連携のリファクタリング
- 03暗黙のパターンや過剰設計のコードレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill implementation-design-patterns-pythonインストール後、Claude Code で/implementation-design-patterns-pythonを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdgotchas.mdmetadata.jsonreferences/_sections.mdbehavioral-chain-of-responsibility.mdbehavioral-command.mdbehavioral-iterator.mdbehavioral-mediator.mdbehavioral-memento.mdbehavioral-observer.mdbehavioral-state.mdbehavioral-strategy.mdbehavioral-template-method.mdbehavioral-visitor.mdcreational-abstract-factory.mdcreational-builder.mdcreational-factory-method.mdcreational-prototype.mdcreational-singleton.mdstructural-adapter.mdstructural-bridge.mdstructural-composite.mdstructural-decorator.mdstructural-facade.mdstructural-flyweight.mdstructural-proxy.md詳細
Python のデザインパターンのベストプラクティス(Refactoring Guru)
**慣用的なモダン Python(3.10+)**での Gang of Four の22種類のデザインパターンの実装リファレンスです。refactoring.guru をもとにまとめています。3つのカテゴリにまたがる22個のパターンファイルには、それぞれ意図、問題、解決策、適用可能性(使う場合と使わない場合)、実行可能な Python の例と出力、実装手順、メリットとデメリット、関連する兄弟パターンが記載されています。
これは、TypeScript のデザインパターンスキルをPython らしさ優先で補完するものです。GoF パターンの多くは、Python では言語機能、つまり関数、ジェネレーター、データクラス、functools.singledispatch、match 文で表現できます。各項目では、まず慣用的な形式を紹介し、オブジェクトの同一性、保持する状態、実行時の登録、ポリモーフィックなディスパッチが本当に必要な場合に限り、GoF のクラスベースの構造を採用します。
パターンは構造を決めるための語彙であり、処方箋ではありません。適用基準に合う場合にのみ使ってください。Python では、このカタログを使う際によくある失敗は過剰設計なので、すべての項目にそれを防ぐための 使わない場合 セクションを設けています。
適用する場面
- コンストラクターのパラメーターが10個以上に増えている(テレスコーピングコンストラクターの兆候)、またはサブクラスがパラメーターの組み合わせを固定するためだけに存在している
- アルゴリズムや動作を選ぶため、メソッドが
kind/type/mode/statusに応じて分岐している — バリエーションが増えるたびに大きくなるmatch文やif/elifの連鎖 - メソッド名がコードと一致しない、互換性のないサードパーティ API、ライブラリ、レガシークラスを統合している
- 葉と枝を同じように扱う必要がある、ツリー状のドメイン(ファイルシステム、AST、UI ツリー、組織図)をモデル化している
- サブクラス化せずに、ログ記録、キャッシュ、アクセス制御、圧縮などの横断的な動作を実行時に追加している
- 設定、ユーザー入力、環境に基づいて、実行時にアルゴリズムや動作のバリエーションを選択している
- 操作の取り消し/やり直し、履歴のスナップショット、トランザクションのロールバック、操作のキューイングやスケジューリングを実装している
- 多数のオブジェクト間で直接相互参照が複雑に絡み合っている — 通信を仲介するハブ
- 何かが変わったときに多くのサブスクライバーへ通知している — イベントシステム、リアクティブなデータフロー
- パターンが暗黙的になっているように見えるコードをレビューしている(巨大な
if isinstance(...)、並行するクラス階層、コピー&ペーストされたアルゴリズムの骨格) — 明示的にするか、Python らしい慣用表現に置き換える
ルールのカテゴリ
| # | カテゴリ | 影響度 | パターン数 | このグループを選ぶ場面 |
|---|---|---|---|---|
| 1 | 生成 | 高 | 5 | オブジェクトの構築が複雑、設定によって異なる、または具象クラスへの密結合が懸念される |
| 2 | 構造 | 高 | 7 | 部品を置き換え可能に保ちながら、クラス/オブジェクトをより大きな構造に組み合わせる |
| 3 | 振る舞い | 高 | 10 | 責任を分散し、実行時にオブジェクトがどのように連携するかを定義する |
使い方
- 形を見極めます。 以下のクイックリファレンスを読み、問題の意図に合うパターンを特定します。パターンに当てはまる問題の多くは、一覧にある表現のいずれかに似ています。
- パターンのリファレンスを読みます。
references/{category}-{pattern}.mdを開きます。意図を確認してから、採用する前に適用可能性と使わない場合を読みます。 - 慣用表現から始めます。 各「正しい例」では、まず Python らしい形式を示しています。代替案のブロックにあるクラスベースの構造が必要でない限り、それを採用してください。
- ドメインに合わせます。 例では、現実的で小規模なドメイン(交通手段、経路プランナー、ドキュメントツリー)を使用しています。マージする前に、用語を自分のドメインに合わせて変更してください。
- 関連パターンを確認します。 各項目の最後には関連パターンがあり、同じ問題で検討する価値のある兄弟パターンを確認できます。
クイックリファレンス
1. 生成パターン(オブジェクトのインスタンス化)
creational-factory-method— レジストリ/ディスパッチ用の辞書を通じて具体クラスを解決します。 「if/elif の分岐を並べずに、設定値や文字列キーでクラスを選びたいです。」 — HIGHcreational-abstract-factory— 互いに対応する関連オブジェクトの一群を生成します。 「フラグを1つ切り替えると、連携する一式(ボタン+チェックボックス)をまとめて切り替えたいです。」 — MEDIUM-HIGHcreational-builder— 複雑なオブジェクトを段階的に構築します。Python では、まずキーワード専用の dataclass を検討します。 「コンストラクターの引数が10個以上ある、または段階的に組み立てる必要があります。」 — HIGHcreational-prototype—copy.deepcopy/dataclasses.replaceを使って複製します。 「これと同じものを、値を1つ変えてもう1つ作りたいです。」 — MEDIUMcreational-singleton— モジュールのグローバル変数またはfunctools.cacheを使って、共有インスタンスを1つだけ用意します。 「テスト可能な状態を保ちつつ、設定/レジストリ/プールを1つだけ用意したいです。」 — MEDIUM
2. 構造パターン(合成)
structural-adapter— クラスをラップして、呼び出し側が期待するインターフェースに合わせます。 「このライブラリのメソッド名が自分のものと一致せず、ライブラリを編集することもできません。」 — HIGHstructural-bridge— 合成+Protocolによって抽象と実装を分離します。 「直交する軸が2つあり、サブクラスの数が増え続けています。」 — MEDIUMstructural-composite— 共通のProtocolと再帰を使い、葉とツリーを統一的に扱います。 「ツリーがあり、項目とグループに同じインターフェースを使いたいです。」 — HIGHstructural-decorator— ラッパーを重ねる(または@decoratorを使う)ことで、実行時に振る舞いを追加します。 「ログ記録+キャッシュ+圧縮を、任意の順序で重ねたいです。」 — HIGHstructural-facade— 複雑なサブシステムに対して、単一の関数/モジュールを公開します。 「コーデックやビットレートの面倒な処理ではなく、convert(file, fmt)だけを使いたいです。」 — HIGHstructural-flyweight— キャッシュ付きファクトリー+__slots__を使って、不変の状態を共有します。 「オブジェクトが数百万個あり、ペイロードの種類はごく少数しかないため、メモリが不足しています。」 — LOW-MEDIUMstructural-proxy—__getattr__/cached_propertyを使って代理となり、アクセスを制御します。 「実際のオブジェクトに手を加えずに、遅延読み込み/認証/キャッシュを実現したいです。」 — MEDIUM-HIGH
3. 振る舞いパターン(連携)
behavioral-chain-of-responsibility— リクエストを順序付けられたハンドラーのリストに渡して処理します。 「順序を入れ替えたい、認証/検証/認可チェックのパイプラインが必要です。」 — MEDIUM-HIGHbehavioral-command— リクエストを、任意で取り消し可能な呼び出し可能オブジェクト/クロージャとして具体化します。 「取り消し/やり直し、キューイング、または複数の UI サーフェスで共有する単一のアクションが必要です。」 — HIGHbehavioral-iterator— 内部を公開せず、__iter__/ジェネレーターを使って走査します。 「for x in my_structureをそのまま動作させたいです。」 — HIGHbehavioral-mediator— 1 つのハブを通じてコンポーネント間のやり取りを仲介します。 「ウィジェット同士が互いを参照していて、再利用できません。」 — MEDIUMbehavioral-memento— 凍結データクラスを使って状態をスナップショット/復元します。 「プライベートフィールドを公開せずに、取り消し/ロールバックしたいです。」 — LOW-MEDIUMbehavioral-observer— 変更時にサブスクライバーのコールバックへ通知します(多くの場合、propertyセッターを使用します)。 「1 つの値が変わったときに、多数のオブジェクトが反応する必要があります。イベントやリアクティブ UI などです。」 — CRITICALbehavioral-state— ポリモーフィックな状態オブジェクト(または enum とディスパッチ)に処理を委譲します。 「クラスがステートマシンになっていて、すべてのメソッドにif status ==があります。」 — MEDIUM-HIGHbehavioral-strategy— アルゴリズムをCallableとして渡し、実行時に切り替えます。 「複数のアルゴリズム(ソート/ルーティング/支払い)を条件分岐なしで選びたいです。」 — HIGHbehavioral-template-method— ABC で処理の骨格を定め、サブクラスで各ステップをオーバーライドします。 「複数のクラスでアルゴリズムを共有しつつ、一部のステップだけを変えたいです。」 — MEDIUMbehavioral-visitor—functools.singledispatch/matchを使って操作を追加します。 「ノードクラスを編集せずに、AST 全体で 5 つの操作を実装したいです。」 — LOW-MEDIUM
類似したパターンの選び方
形が似ていても、異なる問題を解決するパターンがいくつかあります。各パターンの関連パターンのセクションを読み、次の違いを踏まえて選んでください。
- Adapter、Facade、Proxy、Decorator の違い — 4つとも対象をラップします。Adapter はインターフェースを変更します。Facade はサブシステムを簡素化します。Proxy はインターフェースを維持し、アクセスやライフサイクルを制御します。Decorator はインターフェースを維持し、再帰的に振る舞いを追加します。
- Strategy と State の違い — どちらも差し替え可能なオブジェクトに処理を委譲します。Strategy の各バリアントは独立した関数で、呼び出し側が選択します。State オブジェクトは互いを認識し、コンテキストの状態遷移を引き起こします。
- Strategy と Template Method の違い — どちらもアルゴリズムの一部を変化させます。Strategy はコンポジションを使います。実行時に差し替える
Callableです。Template Method は継承を使います。定義時に固定される ABC の骨格です。 - Factory Method、Abstract Factory、Builder の違い — Factory Method は1つのプロダクトを選び出します(レジストリ/
@classmethod)。Abstract Factory は互いに対応するプロダクトのファミリーを返します。Builder は1つの複雑なプロダクトを組み立てます(キーワード専用のデータクラス、または段階的な構築に使う流れるようなインターフェースのビルダー)。 - Composite と Decorator の違い — どちらも子要素を再帰的にラップします。Composite は子要素の結果を集約します。Decorator は1つの責務を追加し、処理をそのまま引き継ぎます。
- Chain of Responsibility、Command、Mediator、Observer の違い — いずれも送信側と受信側をつなぎます。CoR はハンドラーのリストに沿ってリクエストを渡します(途中で止めることもできます)。Command はリクエストを第一級の呼び出し可能オブジェクトにします。Mediator は多対多の通信を一元管理します。Observer は1つのパブリッシャーから複数のサブスクライバーへの通知を確立します。
- Visitor:
singledispatch、match、メソッドの使い分け — クラスを編集せずに、閉じた型集合に対する操作を追加するにはfunctools.singledispatchを使います。すべてのケースを1つの網羅的な関数にまとめたい場合はmatchを使います。操作が1つだけで型の種類が少ない場合は、通常のメソッドを使います。