はじめに
アダプターパターンとは何かを整理します。
アダプターパターンとは
アダプターパターン(Adapter Pattern)は、互換性のないインターフェース同士をつなぐためのデザインパターンです。
例えば、アプリケーションが
$payment->pay(1000);
というインターフェースを期待しているとします。
一方で、利用する外部ライブラリは
$stripe->createPaymentIntent(...);
というメソッドしか提供していないかもしれません。
このままでは、アプリケーションから直接利用できません。
そこで、間にAdapterを用意し、
$payment->pay(1000);
という呼び出しを、
$stripe->createPaymentIntent(...);
へ変換します。
このように、異なるインターフェースを仲介するのがアダプターパターンです。
なぜAdapterが必要なのか
既存のライブラリや外部サービスは、それぞれ独自のインターフェースを持っています。
例えば決済サービスを利用する場合でも、
Stripeと別の決済サービスではメソッド名や引数が異なることがあります。
アプリケーションがそれぞれの仕様を直接扱うようになると、コード全体が外部ライブラリへ依存してしまいます。
そこでAdapterを挟むことで、
アプリケーションは共通のインターフェースだけを利用できるようになります。
変換するのはメソッドだけではない
Adapterはメソッド名を変換するだけではありません。
例えば、
外部APIから
{
"first_name": "Taro",
"last_name": "Yamada"
}
というレスポンスが返ってきたとします。
アプリケーションでは、
$user->fullName();
のようなオブジェクトを扱いたい場合があります。
そのような場合も、
APIのレスポンスをアプリケーションが扱いやすい形へ変換する役割をAdapterが担当できます。
外部APIやSDKでよく使われる
アダプターパターンは、外部サービスとの連携で利用されることが多くあります。
例えば、
- 決済サービス
- GitHub API
- Slack API
- クラウドサービスのSDK
などです。
外部サービス固有の仕様をAdapterへ閉じ込めることで、アプリケーション側はサービスの違いを意識せず利用できます。
Repositoryとの違い
Repository Patternと混同されることがありますが、目的は異なります。
Repositoryは、
データの取得や保存をまとめるための設計パターンです。
一方でAdapterは、
異なるインターフェース同士をつなぐことを目的としています。
例えば、
Application
│
▼
UserRepository
│
▼
GitHubAdapter
│
▼
GitHub API
という構成もあります。
Repositoryは「ユーザーを取得する」という責務を持ち、
GitHub APIとの通信方法やデータ形式の変換はAdapterが担当します。
Adapterを使うメリット
Adapterを利用すると、アプリケーションは外部ライブラリやサービスの実装へ直接依存しなくなります。
例えば、利用する決済サービスを変更する場合でも、
変更が必要になるのはAdapterの実装だけで済むことがあります。
また、アプリケーション全体で同じインターフェースを利用できるため、コードの見通しも良くなります。
おわりに
アダプターパターンは、互換性のないインターフェース同士をつなぐためのデザインパターンです。
外部ライブラリやAPIをそのまま利用するのではなく、アプリケーションが扱いやすい形へ変換することで、依存関係を整理しやすくなります。
外部サービスとの連携が増えるほど、アダプターパターンの役割を意識する場面も多くなります。