← Назад к вопросам
В чем разница между фасадом и адаптером?
2.3 Middle🔥 151 комментариев
#Архитектура и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Фасад (Facade) vs Адаптер (Adapter)
Оба паттерна решают проблемы интеграции и упрощения работы с кодом, но подходят к этому по-разному.
Адаптер (Adapter) — преобразование интерфейса
Адаптер преобразует один интерфейс в другой, чтобы несовместимые компоненты работали вместе.
class Duck:
def quack(self):
pass
def fly(self):
pass
class Turkey:
def gobble(self):
print("Gobble gobble")
def fly(self):
print("Turkey flying")
# АДАПТЕР: Преобразуем Turkey в Duck
class TurkeyAdapter(Duck):
def __init__(self, turkey):
self.turkey = turkey
def quack(self):
self.turkey.gobble()
def fly(self):
self.turkey.fly()
turkey = Turkey()
adapter = TurkeyAdapter(turkey)
adapter.quack() # Работает!
def duck_simulator(duck):
duck.quack()
duck.fly()
duck_simulator(adapter) # Turkey работает как Duck
Фасад (Facade) — упрощение сложной системы
Фасад скрывает сложность системы и предоставляет простой интерфейс для работы с несколькими компонентами.
class Amplifier:
def on(self): print("Усилитель включён")
def off(self): print("Усилитель выключен")
def set_volume(self, level): print(f"Громкость: {level}")
class DVDPlayer:
def on(self): print("DVD включен")
def off(self): print("DVD выключен")
def play(self, movie): print(f"Проигрываем {movie}")
class Projector:
def on(self): print("Проектор включен")
def off(self): print("Проектор выключен")
class Lights:
def dim(self, level): print(f"Освещение: {level}%")
# ФАСАД: Скрывает сложность
class HomeTheaterFacade:
def __init__(self, amp, dvd, projector, lights):
self.amp = amp
self.dvd = dvd
self.projector = projector
self.lights = lights
def watch_movie(self, movie):
print("Подготовка к просмотру фильма...")
self.lights.dim(10)
self.projector.on()
self.amp.on()
self.amp.set_volume(5)
self.dvd.on()
self.dvd.play(movie)
def end_movie(self):
print("Завершение просмотра...")
self.lights.dim(100)
self.projector.off()
self.amp.off()
self.dvd.off()
theater = HomeTheaterFacade(
Amplifier(), DVDPlayer(), Projector(), Lights()
)
theater.watch_movie("Матрица")
theater.end_movie()
Сравнение в таблице
| Аспект | Адаптер | Фасад |
|---|---|---|
| Цель | Преобразовать интерфейс | Упростить сложную систему |
| Проблема | Несовместимые интерфейсы | Сложность системы |
| Направление | Двусторонний | Одностороннее |
| Количество компонентов | Обычно 1-2 | Много |
| Отношение к исходному коду | Оборачивает один объект | Скрывает множество объектов |
Практические примеры
Адаптер: интеграция разных API
class HttpClient:
def get(self, url):
pass
def post(self, url, data):
pass
import requests
class RequestsAdapter(HttpClient):
def get(self, url):
response = requests.get(url)
return response.json()
def post(self, url, data):
response = requests.post(url, json=data)
return response.json()
api_client = RequestsAdapter()
api_client.get("https://api.example.com/users")
Адаптер: старый и новый код
class LegacyPaymentProcessor:
def process_payment(self, cc_number, amount):
print(f"Обработка платежа: {cc_number} на сумму {amount}")
class ModernPaymentProcessor:
def process_secure_payment(self, token, amount):
print(f"Безопасная обработка: {token} на сумму {amount}")
class PaymentAdapter(ModernPaymentProcessor):
def __init__(self, legacy_processor):
self.legacy = legacy_processor
def process_payment_v2(self, cc_number, amount):
token = f"TOKEN_{hash(cc_number)}"
self.process_secure_payment(token, amount)
processor = PaymentAdapter(LegacyPaymentProcessor())
Фасад: работа с БД
class QueryBuilder:
def __init__(self):
self.conditions = []
def where(self, field, value):
self.conditions.append(f"{field} = {value}")
return self
class ConnectionPool:
def get_connection(self):
return "connection"
class Logger:
def log_query(self, query):
print(f"Executing: {query}")
class DatabaseFacade:
def __init__(self):
self.query_builder = QueryBuilder()
self.pool = ConnectionPool()
self.logger = Logger()
def find_users(self, **filters):
qb = QueryBuilder()
for field, value in filters.items():
qb.where(field, value)
query = " ".join(qb.conditions)
self.logger.log_query(query)
conn = self.pool.get_connection()
return f"Results from: {query}"
db = DatabaseFacade()
users = db.find_users(active=True, role="admin")
Когда использовать что
Адаптер используй когда:
- Нужно интегрировать несовместимые интерфейсы
- Работаешь с third-party библиотеками
- Нужна поддержка нескольких версий API
- Преобразуешь данные из одного формата в другой
Фасад используй когда:
- Система имеет много компонентов
- Хочешь упростить API для клиентов
- Нужно скрыть внутренние детали реализации
- Уменьшить связанность компонентов
Важное отличие
- АДАПТЕР: я хочу, чтобы несовместимое работало вместе — СОВМЕСТИМОСТЬ
- ФАСАД: я хочу упростить использование сложной системы — УПРОЩЕНИЕ
- Адаптер: "Я буду говорить на языке обеих сторон"
- Фасад: "Используй меня, я все скрыл"