Объектно-ориентированные парадигмы стали более популярными в Javascript с введением нового синтаксиса ES6, а точнее class. Классы - это здорово, и они определенно помогут вам лучше структурировать код. Однако проблема возникает, когда вы хотите объединить функциональность нескольких классов вместе и при этом обеспечить модульность своего кода. Итак, в этом посте я хочу поговорить о Composable Factory Functions (CFF), которые позволяют создавать объекты, объединяющие несколько многоразовых функций, без создания тесно связанной иерархии классов.

Фабрика

Фабрика - хорошо известный паттерн в мире программирования. С помощью factory вы абстрагируете создание объекта с помощью специальной функции factory и используете эту функцию только для создания новых экземпляров объекта. Потребитель фабрики не знает, как создается объект, что дает нам свободу реализации фабричной функции. Давайте посмотрим на пример.

Генерация токенов безопасности

В этом примере мы собираемся написать простую фабричную функцию для генерации кода безопасности для связи между нашим сервером и интерфейсом:

Теперь у вас может возникнуть соблазн просто использовать jsonwebtoken библиотеку непосредственно в вашем клиентском коде, не создавая для нее отдельный фабричный метод. Это нормально, если вы генерируете токен только в одном месте, но если в вашем коде есть несколько мест, которые генерируют токен, изменение реализации будет проблематичным.

Добавление доступа администратора

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

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

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

Составные фабричные функции

Составные фабричные функции (CFF) - это более продвинутый шаблон Node.JS, который строится поверх фабричного шаблона. В этом шаблоне фабричные функции могут быть скомпонованы вместе, чтобы создать другую фабричную функцию с комбинированными функциями.

Генератор супергероев

Вот простой пример использования CFF для создания объектов, сочетающих в себе несколько функций. Поскольку скоро выйдет новый фильм «Мстители», давайте представим, что мы создаем эмулятор создания супергероев. Мы хотим создать супергероев нового типа на основе предоставляемых нами основных атрибутов и способностей.

В этом примере мы собираемся использовать библиотеку stampit для построения CFF. Этот легкий модуль предоставляет нам простой API для создания фабричных функций.

Итак, вот 5 основных CFF:

  • Персонаж - базовый персонаж, у которого есть очки жизни, очки выносливости и имя.
  • Полет - дает персонажу возможность летать.
  • Суперсила - персонаж со сверхчеловеческой силой
  • Интеллект - персонаж обладает интеллектом гениального уровня.
  • Боевые искусства - делает персонажа экспертом в боевых искусствах.

Начнем с базовой функции Character:

props используется для определения свойств объекта по умолчанию

  • init определяет свойства, которые мы можем назначить в процессе инициализации

Теперь добавим остальные CFF!

Как видите, у нас есть 4 разных сверхмощных CFF, каждый со своими собственными методами. Теперь давайте посмотрим, как мы можем объединить их для создания составных фабричных функций:

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

Наконец, давайте создадим несколько экземпляров составных объектов:

Просто не правда ли? При создании новых экземпляров мы должны предоставить начальные значения, которые были определены в методе init для каждой фабричной функции.

Вот и все! Надеюсь, вы сочли это полезным. Составные фабричные функции во многих случаях являются отличной альтернативой классам. Они позволяют создавать многократно используемый и слабо связанный код при создании функциональных возможностей сложных объектов.

Первоначально опубликовано на сайте isamatov.com 14 апреля 2019 г.