В чем ключевое различие между паттернами проектирования Фасад и Адаптер

Ответ

Оба паттерна являются структурными, но решают принципиально разные задачи: Фасад упрощает интерфейс, а Адаптер преобразует его.

Фасад (Facade)

Цель: Предоставить простой, единый интерфейс для сложной подсистемы. Он скрывает внутреннюю сложность и множество компонентов за одной "дверью".

Аналогия: Пульт управления "умным домом". Одна кнопка "Я ухожу" может выключить свет, закрыть шторы и активировать сигнализацию, скрывая взаимодействие с каждой из этих систем.

Пример (Python):

# Сложная подсистема
class VideoConverter:
    def convert(self, filename, format): ...

class AudioExtractor:
    def extract(self, filename): ...

class Uploader:
    def upload(self, file): ...

# Фасад, упрощающий работу
class MediaProcessingFacade:
    def __init__(self):
        self.video = VideoConverter()
        self.audio = AudioExtractor()
        self.uploader = Uploader()

    def process_and_upload(self, filename):
        print(f"Начинаем обработку файла {filename}")
        self.video.convert(filename, 'mp4')
        self.audio.extract(filename)
        self.uploader.upload(f"{filename}.mp4")
        print("Обработка завершена.")

# Клиентский код
facade = MediaProcessingFacade()
facade.process_and_upload("my_movie.mov")

Адаптер (Adapter)

Цель: Обеспечить совместную работу классов с несовместимыми интерфейсами. Он действует как переводчик между двумя объектами.

Аналогия: Переходник для розетки, который позволяет подключить американскую вилку (один интерфейс) к европейской розетке (другой интерфейс).

Пример (Python):

# Существующий класс с несовместимым интерфейсом
class OldLogger:
    def log_message(self, text):
        print(f"LOG: {text}")

# Новый стандартный интерфейс
class Logger:
    def info(self, message): ...

# Адаптер, который "подгоняет" OldLogger под новый интерфейс
class LoggerAdapter(Logger):
    def __init__(self, old_logger: OldLogger):
        self.old_logger = old_logger

    def info(self, message):
        # Преобразование вызова
        self.old_logger.log_message(message)

# Клиентский код работает с новым интерфейсом
logger = LoggerAdapter(OldLogger())
logger.info("Это сообщение будет записано через старый логгер.")