С примерами, которые помогут вам это реализовать

Вы когда-нибудь сталкивались с кодом, в котором какая-либо функция имела суффикс Adapter? Скорее всего, вы читали код, включающий совместимость в поведении двух интерфейсов с использованием шаблона адаптера. В этой статье мы рассмотрим шаблон адаптера в JavaScript и объясним, почему этот шаблон важен и почему он может быть полезен в современном программировании.

Способ работы адаптера заключается в том, что вы создаете функцию (которая может быть классом, но не должна быть реализована как класс), которая легко адаптирует свойства и методы своего интерфейса в новый класс. - как если бы адаптер все еще можно было идентифицировать и вести себя как оригинал, в то же время имея возможность работать с новым интерфейсом.

Поскольку веб-технологии в JavaScript постоянно развиваются, легко увидеть, что этот шаблон используется сегодня в проектах с открытым исходным кодом (например, axios-mock-adapter).

Как это выглядит

Нет правильного способа написать шаблон адаптера на JavaScript. Однако все они преследуют одну и ту же цель: обеспечить совместимость одного интерфейса с другим.

Например, если у нас есть функция, которая принимает список объектов (каждый из которых мы будем называть объекты действия в следующем примере) и преобразует их в Action экземпляры в массиве перед передачей их другому функция, которая вызывает каждый из их execute методов, то любые новые введения в реализацию должны следовать этому аналогичному интерфейсу, если они хотят сохранить совместимость.

Давайте возьмем эти объекты действий, которые имеют общее свойство actionType:

Учитывая эти классы, мы определяем:

Допустим, у нас есть ActionChain, который принимает массив объектов действия и подготавливает их к выполнению:

Каждое действие будет выполняться в нашем приложении без проблем, потому что все они имеют совместимый интерфейс.

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

Допустим, мы работаем во внешнем интерфейсе компании, и наш менеджер группы хочет заменить / исключить объекты pageJump (например, { actionType: "pageJump", destination: "/contact" }) на более короткий синтаксис, например { goto: "/contact" }. Если мы внесем это изменение в наше приложение, наш код сломается. Это потому, что наш бегун runActions выполняет свой execute метод, которого нет в новом синтаксисе.

Мы можем обойти эту проблему, поддерживая действие goto с помощью адаптера, чтобы программа могла вести себя таким же образом.

Мы можем начать с создания класса, расширяющего базу Action:

Поскольку goto по сути является просто другой версией pageJump (их конечная цель такая же), мы можем определить другой адаптер, который может принимать любой из двух и возвращать то, что можно запустить в ActionChain:

Таким образом, мы можем сохранить одинаковое поведение наших pageJump действий. Не только это, но мы также можем заставить их использовать расширенные методы, которые есть у goto (например, иметь доступ к this.history и устанавливать новые URL-адреса, когда захотим).

Теперь мы можем продолжить разработку приложения, избегая критических изменений при переносе части старого кода:

Другие примеры

Я считаю, что больше примеров с разных точек зрения помогут разработчикам лучше понять концепции, поэтому вот еще несколько примеров, в которых используется этот шаблон.

Калькулятор

Вот пример, взятый из сути:

Если приложение-калькулятор было написано с использованием OldCalculator, и вы хотите предоставить ему способ работы с NewCalculator интерфейсом, вам нужен способ сопоставить NewCalculator, где их поведение работает одинаково.

Пример ниже написан с использованием адаптера, который решает проблему:

Адаптер Axios

Ранее в статье я упоминал axios-mock-adapter, который использует в своем коде шаблон адаптера для обеспечения совместимости, поддерживая использование обещаний и оригинальный подход обратного вызова:

Это отличный пример, потому что их синтаксис заметно отличается. Однако в конце концов они оба достигают своей цели. Это прекрасно настраивается!

Заключение

На этом статья завершается! Надеюсь, вы нашли это ценным. Ожидайте большего в будущем!