2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで実装するAdapterパターン:インターフェースの不整合を滑らかに接続する

Posted at

概要

Adapter(アダプター)パターンは、
互換性のないインターフェース同士を中継するクラスを用意し、スムーズに連携させる設計パターンである。

既存のライブラリや外部システム、古いAPIを現代的なインターフェースへと変換する用途に最適
Pythonでは柔軟な動的型付けとDuck Typingにより、特に適用しやすい。


1. なぜAdapterが必要か?

❌ 異なるインターフェースをそのまま使おうとすると冗長な変換が必要

# 想定:.read() を使いたいが .load() しかない
data = legacy_loader.load()
stream = io.BytesIO(data)

呼び出し側が変換処理を背負う構造になる


✅ Adapterを導入し、変換をカプセル化

adapter = LegacyLoaderAdapter(legacy_loader)
data = adapter.read()

呼び出し側は理想的なインターフェースに統一される


2. 基本構造

✅ 想定されるインターフェース(Target)

class Reader:
    def read(self):
        raise NotImplementedError

✅ 適応対象(Adaptee)

class LegacyLoader:
    def load(self):
        return "データをロード"

✅ Adapter(中継クラス)

class LegacyLoaderAdapter(Reader):
    def __init__(self, adaptee: LegacyLoader):
        self.adaptee = adaptee

    def read(self):
        return self.adaptee.load()

✅ 使用例

legacy = LegacyLoader()
reader = LegacyLoaderAdapter(legacy)

print(reader.read())

出力:

データをロード

3. Python的応用:Duck Typingによる暗黙的Adapter

class FileLikeAdapter:
    def __init__(self, string_data):
        self._buffer = string_data

    def read(self):
        return self._buffer
# 通常 read() を期待する関数でも使える
def process(reader):
    print(reader.read())

adapter = FileLikeAdapter("適応されたデータ")
process(adapter)

Pythonでは抽象クラスを継承せずとも、read() を持つだけで代用可能


4. 実務ユースケース

✅ 外部APIのインターフェース変換(旧バージョン → 新設計)

依存コードに影響を与えずにラップで対応可能


✅ データフォーマットの差異調整(CSV → JSON / XML → Dict)

→ 各形式の入出力を標準インターフェースに揃える


✅ Webサービス間のクライアント仕様差の吸収

→ REST → SDK、gRPC → 関数呼び出し等の接続層整形


✅ テスト用のモッククラス作成時のインターフェース適合

異なる構造を持つオブジェクトをテストに使えるようにする


5. よくある誤用と対策

❌ Adapterが複雑化しすぎる(責務を持ちすぎる)

→ ✅ 単に“インターフェースを揃える”ことだけに注力する


❌ Adapteeの全機能をラップしてしまう

→ ✅ 実際に必要なメソッドのみをラップすることで簡潔性を維持


❌ 呼び出し側で再びAdapteeにアクセスしてしまう

→ ✅ Adapterを経由することを前提とした構造にリファクタリング


結語

Adapterパターンとは、“異なる世界のルールを橋渡しし、統一された文脈へ変換する設計”である。

  • インターフェースの不一致を吸収し、整合性のあるアーキテクチャを構築
  • 外部依存を内部構造に適応させ、保守性と柔軟性を確保
  • Pythonではクラス・関数・Duck Typingの柔軟性により、極めて簡潔に設計可能

Pythonicとは、“外との違いを受け入れつつ、内では一貫性を保つこと”。
Adapterパターンはその調和を、設計の結合点に置くための知恵である。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?