Что такое паттерн адаптер
Что проверяют
Понимаете ли вы, что паттерн решает задачу несовместимых интерфейсов, а не «обёртки вообще», и умеете ли отличать его от декоратора и фасада. В Python есть дополнительный слой: утиная типизация снимает половину поводов для адаптера, и интервьюер смотрит, чувствуете ли вы эту границу.
Как отвечать
Адаптер переводит интерфейс существующего объекта в тот, который ожидает клиент, не меняя ни клиента, ни адаптируемый код. Участников трое: клиент со своим ожиданием, чужой объект (библиотека, устаревший модуль, клиент внешнего API) и адаптер между ними.
class PaymentAdapter:
def __init__(self, legacy):
self._legacy = legacy
def pay(self, amount: Decimal) -> Receipt:
raw = self._legacy.do_payment(cents=int(amount * 100))
if raw["status"] != "OK":
raise PaymentError(raw["code"])
return Receipt(id=raw["tx"], amount=amount)Подчеркните два момента. Первый: адаптер собирают композицией, а не наследованием от чужого класса, иначе вместе с методами наследуются его инварианты и приватная кухня. Второй: переводить приходится не только имена методов, но и единицы измерения, типы и ошибки, как в примере выше, где чужой код отвечает словарём, а наружу уходит своя структура и своё исключение.
В Python отдельный целевой абстрактный класс обычно не нужен: достаточно, что адаптер реализует ожидаемые методы, а для статической проверки берут typing.Protocol.
Где спотыкаются
Путают с соседями по разделу. Декоратор сохраняет интерфейс и добавляет поведение, фасад упрощает вход в сложную подсистему, прокси управляет доступом. Адаптер один меняет форму интерфейса, не трогая суть операции.
Наследуют адаптер сразу от целевого базового класса и от адаптируемого. Получается класс с двумя наборами методов, где клиент случайно зовёт исходный do_payment в обход перевода, и смысл изоляции пропадает.
Отращивают в адаптере бизнес-логику. Признак прост: внутри появились ветвления по данным, а не по формату ответа. Тонкий адаптер тестируется подстановкой фейкового объекта за пару строк, разросшийся требует поднимать половину приложения.