「使いたいライブラリがあるけれど、メソッド名やデータの形が自分のコードと合わない…」そんな経験はありませんか?
アダプタパターンは、まさにこの“かみ合わない”を解決するためのデザインパターンです。
互換性のないインターフェース同士をつなぎ、既存コードをほとんど変えずに再利用できるようにします。 Pythonの初心者でもイメージしやすいように、日常の「電源プラグ変換」を例にして、わかりやすく解説していきます。
最初にイメージをつかみましょう。日本の家電は100V、ヨーロッパのコンセントは230Vです。差し込み口や電圧が違うとそのままでは使えませんよね。 そこで登場するのが「変換プラグ(アダプタ)」。アダプタを間に挟むと、異なる規格同士でも安全に接続できます。
プログラミングでも同じことが起きます。クライアント(使う側)が期待するインターフェース(メソッドやデータ形式)と、既存のクラス(使われる側)のインターフェースが合わない。その“ズレ”を埋めるのがアダプタパターンです。
いきなり細かい話に入る前に、どんな場面で役立つのか、ゴールを明確にしておきましょう。 アダプタパターンの主な目的は次のとおりです。
「外部APIの仕様が変わった」「レガシーコードを新設計に組み込みたい」など、現実の開発でよくある悩みに効くのがアダプタパターンです。
アダプタパターンの構成要素を知ると、コードがグッと読みやすくなります。ここでは、難しい言葉を身近な言い換えと一緒に紹介します。
ここからは、Pythonで動くサンプルを通して具体的に理解していきましょう。 今回は「100Vしか出せない既存クラス」を「230Vが欲しいクライアント」に接続するアダプタを作ります。電気的な正確さではなく、あくまで“形を合わせる”イメージに注目してください。
class EuropePowerSource:
"""ターゲット: クライアントが期待するインターフェース(230Vを出力)"""
def output_230v(self) -> int:
raise NotImplementedError
class JapanOutlet:
"""アダプティ: 既存のインターフェース(100Vを出力)"""
def output_100v(self) -> int:
return 100
class JapanToEuropeAdapter(EuropePowerSource):
"""アダプタ: EuropePowerSourceの顔でJapanOutletを内部で利用する"""
def __init__(self, outlet: JapanOutlet) -> None:
self._outlet = outlet
def output_230v(self) -> int:
# 実際の電圧変換ではありません。学習のための簡略化です。
# 100V -> 230V へ変換した「ことにする」。
base = self._outlet.output_100v()
return int(base * 2.3) # 100 * 2.3 = 230
def use_eu_device(source: EuropePowerSource) -> None:
"""クライアント: 230Vを出せる“誰か”にだけ依存"""
volts = source.output_230v()
print(f"230V対応機器を起動します… 受電: {volts}V")
# 実行例
jp_outlet = JapanOutlet() # 既存(100V)
adapter = JapanToEuropeAdapter(jp_outlet) # 変換アダプタ
use_eu_device(adapter) # クライアントは230Vだけを意識
最初に、クライアントが欲しがっているのは「230Vを出せる電源(EuropePowerSource)」です。しかし手元にあるのは「100Vしか出せない日本のコンセント(JapanOutlet)」。
このままでは差し込めません。そこで変換アダプタ(JapanToEuropeAdapter)を作り、表向きはEuropePowerSourceとして振る舞いながら、裏側ではJapanOutletを呼び出します。
クライアント関数use_eu_deviceはとても素直です。「230Vを出せる相手」さえもらえれば満足。相手が本当にヨーロッパのコンセントなのか、変換アダプタなのか、はたまた他の何かなのかは気にしません。これが依存を減らす設計の力です。
現場で「これ、アダプタパターンが使えるかも」と感じる瞬間は、次のようなときです。思い当たるものはありますか?
ここまでの流れを踏まえて、得られるメリットを改めて押さえておきましょう。
アダプタパターンは、互換性のないインターフェース同士を「間に挟んで」つなぐための基本テクニックです。
クライアントが期待する形を守りながら、既存資産を安全に再利用できます。外部API、レガシーコード、ライブラリ移行など、実務での出番はとても多いもの。もし「インターフェースが合わない…」と感じたら、まずはアダプタで“形を合わせられないか”を検討してみましょう。きっと、コードの変更範囲を小さく、影響を局所化できるはずです。
小さく試して、少しずつ慣れていけば大丈夫です。次に既存コードと新しいコードをつなぐ場面が来たとき、あなたは迷わず「アダプタを作ろう」と判断できるようになります。