gof-adapter について
gof-adapterは、互換性のないインターフェースをつなぐ設計パターンを学ぶ開発者向けスキルです。オブジェクトアダプターとクラスアダプター、適用判断や注意点を解説します。
主な機能
- 01オブジェクト/クラスアダプター
- 02境界でのインターフェース変換
- 03アダプターの範囲を絞る指針
- 04アンチパターンと関連パターン
活用シーン
- 01互換性のないライブラリの統合
- 02新旧 API の段階的な移行
- 03変更できないシステム間の接続
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ yonatankarp/ software-design-skills --skill gof-adapterインストール後、Claude Code で/gof-adapterを入力して読み込まれたか確認します。
詳細
1 行でまとめると
あるインターフェースを、クライアントが期待する別のインターフェースに変換します。互換性のないインターフェースのために本来は連携できないクラス同士を連携できるようにします。
このスキルを使う場面
- コードが期待するものとは異なるインターフェースを持つサードパーティー製ライブラリを統合するとき。
- 古い API から新しい API に移行するとき。新しい API(またはその逆)を使って古いインターフェースを提供するアダプターを作成し、段階的に切り替えます。
- どちらのシステムも変更できないものの、両者を連携させる必要があるとき。アダプターをその間に配置します。
- アダプターの典型例は、米国のプラグを欧州のコンセントに差し込めるようにする電源プラグアダプターです。電流そのものは同じで、異なるのはインターフェースだけです。
このスキルを使わない場面
- 2 つのインターフェースが概念的に本質的に異なる目的を持つとき。アダプターで変換すると、実際に必要なドメイン上の判断が隠れてしまいます。その判断を明示してください。
- 1 つのメソッドだけを調整すればよく、ホストクラスを変更してソースを直接呼び出せるとき。アダプターは過剰です。
- ラッパーが「インターフェースを変更する」のではなく、「振る舞いを追加する」とき。それは
gof-decoratorです。 - ラッパーがサブシステムの「複雑さを隠す」とき。それは
gof-facadeです。
主な内容
構造には 2 つのバリエーションがあります。
オブジェクトアダプター(一般的なもの)。アダプターは適合対象のインスタンスへの参照を保持し、委譲によってターゲットインターフェースを実装します。コンポジションベースです。あらゆる OO 言語で使用できます。
クラスアダプター。アダプターはターゲットと適合対象の両方を継承します(多重継承が必要なため、C++ 以外ではまれです)。サブクラスベースです。
HFDP の動機付けとなる例は、Iterator と Enumeration の変換です。レガシーコードは Enumeration を返し、現代のコードは Iterator を期待します。EnumerationIterator アダプターはレガシーコードをラップし、現代的なインターフェースを提供します。
双方向アダプター(両方のインターフェースを満たし、どちらの方向にも変換するアダプター)もありますが、対応範囲が倍になり、労力に見合うことはほとんどありません。
判断のヒント
- 自分のコードと外部コードの境界にアダプターを作成してください。ドメインの奥深くに置いてはいけません。
- アダプターは範囲を絞ってください。インターフェース全体ではなく、自分のコードが実際に使用するターゲットメソッドだけを実装します。
- アダプターは変換レイヤーです。アダプターにビジネスロジックが入り始めたら、そのロジックは別の場所に置くべきです。
アンチパターン
- 「統合レイヤーとしてのアダプター」――認証、再試行、キャッシュ、ロギングまで担うようになったアダプターです。それぞれの関心事を分離してください。
- 適合対象からの例外を黙って握りつぶすアダプター。アダプターは障害も変換しなければなりません。
- 自分のコードをラップするアダプター。両側とも自分のコードなら、アダプターを介すのではなく、どちらかを変更してインターフェースを合わせてください。
関連項目
gof-decorator— 構造は同じですが、目的が異なります(Decorator は振る舞いを追加し、Adapter はインターフェースを変更します)。gof-facade— 単一クラスのインターフェースを別のものに変えるのではなく、サブシステム(複数のクラス)をよりシンプルなインターフェースでラップするときに使います。gof-proxy— オブジェクトへのアクセスを制御するときに使います。インターフェースを変更するものではありません。- DDD
ddd-context-mapping— 腐敗防止層は、境界づけられたコンテキストの境界に置くアダプターです。 gof-kotlin-idioms— Kotlin の拡張関数は、クラスを導入せずに単一メソッド用の一時的なアダプターとして機能します。
参考資料
- Head First Design Patterns(第 2 版)、第 7 章(「適応性を身につける:アダプターとファサードのパターン」)――アヒルを七面鳥に適合させるアダプターの例を含む、定番の章です。
コメント
Markdown 対応