2
2

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(アダプター)パターンは、
互換性のないインターフェース同士を繋ぐ“変換層”を設けることで、
既存コードと新コードをシームレスに連携させる構造パターン
である。

Pythonの柔軟な型システムとダックタイピングにより、
このパターンは非常に実用性が高く、既存ライブラリの置き換えや外部モジュールの統合に多用される。


1. なぜAdapterが必要か?

❌ 既存コードのインターフェースに依存した構造

class LegacyPrinter:
    def print_text(self, txt):
        print(txt)
def render(printer):
    printer.print(txt="Hello")  # エラー!print()なんてない

既存コードを壊さずに、新しい仕様へ適合させたい


✅ Adapterでインターフェースの橋渡しを行う

class PrinterAdapter:
    def __init__(self, legacy):
        self.legacy = legacy

    def print(self, txt):
        self.legacy.print_text(txt)

インターフェースの変換により、互換性を確保


2. 基本構造

✅ 旧API(適合対象)

class LegacyAudioPlayer:
    def play_mp3(self, filename):
        print(f"Playing MP3: {filename}")

✅ 新API(期待されるインターフェース)

class AudioPlayer:
    def play(self, filename):
        raise NotImplementedError

✅ Adapterクラス

class Mp3Adapter(AudioPlayer):
    def __init__(self, legacy_player):
        self.legacy = legacy_player

    def play(self, filename):
        self.legacy.play_mp3(filename)

✅ 使用例

legacy = LegacyAudioPlayer()
player = Mp3Adapter(legacy)

player.play("song.mp3")  # → Playing MP3: song.mp3

3. Python的応用:関数アダプタ、ラッパー関数

✅ 構造体の属性名変更に対して関数で対応

def adapter_wrapper(obj):
    return {
        "name": obj.full_name,
        "email": obj.mail_address
    }

✅ 外部ライブラリのクラスをラップする

from external_lib import ComplexParser

class SimpleParser:
    def __init__(self):
        self.parser = ComplexParser()

    def parse(self, content):
        return self.parser.process(content)  # 外部のmethod名を抽象化

4. 実務ユースケース

✅ 外部APIのクライアントライブラリ統一

requests, urllib3, httpx のような異なるHTTPクライアントの統一インターフェース化


✅ データ形式変換(JSON, XML, YAML)

→ 既存クラスの出力を別形式に変換するためのデコレーター・アダプタ設計


✅ モックと実クラスの橋渡し

→ テスト時はAdapter経由でMockを注入、本番時は実クラスに差し替え可能


5. よくある誤用と対策

❌ Adapterが処理ロジックまで持ち始める

→ ✅ アダプタはあくまで“橋渡し”に徹する。ビジネスロジックは委譲先に任せる


❌ 利用者がAdapterを意識しすぎてしまう

→ ✅ 抽象インターフェースを介して実装の差異を意識させない設計に


❌ AdapterとDecoratorの混同

→ ✅ Adapterはインターフェース変換、Decoratorは機能の付加
目的が異なることを理解して使い分ける


結語

Adapterパターンとは、“インターフェースの不一致を吸収し、設計の整合性を保つための変換レイヤー”である。

  • 過去資産や外部ライブラリと、現在のコードベースの橋渡し役
  • 抽象化と疎結合を実現し、拡張・置換・テストの柔軟性を大幅に向上
  • Pythonの構文的柔軟性により、アダプタ実装は極めてシンプルかつ強力

Pythonicとは、“差異を受け入れ、意図を揃える設計”であり、
Adapterパターンはその整合性と互換性を、構造として確保する技法である。

2
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?