Адаптер помогает в работе с несколькими независимыми компонентами с несовместимыми интерфейсами.

У нас часто есть несколько возможных решений для данной задачи. Очень важно иметь один и тот же интерфейс, чтобы легко переключаться между реализациями. Проблема в том, что мы не всегда контролируем эти компоненты. Адаптер помогает использовать компоненты с несовместимыми интерфейсами. Если вы хотите подключить компьютер к источнику питания и много путешествовать, удобно иметь блок питания, поддерживающий несколько типов розеток. Вашему компьютеру не должно быть важно, какой тип розетки вы используете, и вы должны иметь возможность менять его по мере необходимости. Шаблон проектирования адаптера работает так же, как адаптеры питания.

Мы создаем приложение, которое хранит файл, отправленный пользователем, в каталоге. По мере того, как наше приложение начало расти, количество пользователей и файлов увеличивается. Нашему серверу сейчас не хватает места на диске, и мы хотим начать использовать облачные решения. Облачное файловое хранилище, такое как Azure Blob Storage или AWS S3, кажется хорошим выбором. Чтобы использовать эти функции, мы будем использовать официальные сторонние библиотеки. Маловероятно, что они будут иметь тот же интерфейс, что и используемый в настоящее время компонент. Для облегчения работы с ними мы можем создать оболочку, использующую только необходимые нам функции из этих библиотек, и предоставить наиболее удобный интерфейс. После этого мы сможем легко переключаться между локальным хранилищем, Azure, AWS или любым другим.

Пользовательский интерфейс нашего приложения очень прост. Мы можем загрузить файл и выбрать, где он будет храниться. Мы также можем скачивать и удалять ранее загруженные файлы. Назовем это приложение Total Storage. У нас даже есть логотип!

Сначала у нас был только простой поставщик файлов, который использует локальное хранилище и помещает файл в каталог.

Он использует базовый интерфейс, который определяет, как добавлять, читать и удалять файл.

Метод get должен возвращать не файлы напрямую, а неизменный File объект, который предоставляет доступ к своим свойствам.

Сейчас наше приложение использует только локальное хранилище. Мы до сих пор не знаем, каких дополнительных поставщиков хранилища мы хотим использовать. Более того, мы хотим как можно меньше менять наше приложение. Самый простой способ реализовать хранилище BLOB-объектов Azure - использовать их официальную библиотеку microsoft/windowsazure. Чтобы использовать его, нам нужно создать файл конфигурации с нашими учетными данными для провайдера. Мы будем использовать symfony/dotenv. Вся конфигурация будет храниться в файле .env, который не будет версией и может переключаться между средами. Теперь можно приступить к реализации.

Прямо сейчас мы можем переключиться на Azure, когда захотим. Для использования AWS S3 мы также будем использовать официальный пакет aws/aws-sdk-php. Реализация этого провайдера также должна использовать тот же FileAdapter интерфейс.

Мы не будем вдаваться в подробности настройки учетных записей Azure и AWS, поскольку это выходит за рамки данной статьи. Дело в том, чтобы показать, как мы можем интегрировать полностью независимые решения с использованием шаблона адаптера. Все, что нам нужно сделать, это выбрать подходящую реализацию FileAdapter. Детали реализации для клиента несущественны.

Подводить итоги. Адаптер состоит из следующих элементов:

  • Target (FileAdapter) - интерфейс, который ожидает использовать клиент.
  • Adaptee (BlobRestProxy, S3Client) -элементы, нуждающиеся в адаптации ,
  • Адаптер (LocalFileStorage, AzureFileStorage, _13 _) - позволяет адаптерам работать с целевым интерфейсом

Преимущества:

  • отделение интерфейса от реализации
  • делает возможным использование компонентов с несовместимыми интерфейсами
  • упрощает внедрение новых функций

Полный исходный код и некоторые другие шаблоны доступны здесь:



Если вы хотите изучить еще несколько полезных шаблонов дизайна, вы можете найти их в следующих статьях: