Шаблоны проектирования JavaScript, часть 1: фабричный шаблон

В последнее время, когда проекты, над которыми у меня была возможность работать, выросли в масштабе, я нашел время, чтобы глубже погрузиться в шаблоны проектирования для написания более удобного в сопровождении и масштабируемого кода Javascript. Шаблоны проектирования — это отличный способ применить проверенные временем и боем решения для общих проблем, чтобы мы могли быстрее и эффективнее их решать.

Большинство шаблонов проектирования, которые мы рассмотрим, основаны на объектно-ориентированном программировании, и поэтому имеет смысл только начать с рассмотрения шаблона создания, названного так потому, что шаблон предоставляет нам четкий интерфейс для создания объектов при абстрагировании. разнообразная сложность или логика, связанные с их созданием. Этот шаблон называется Factory Pattern и позволяет нам легко создавать объекты в JavaScript.

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

На самом деле мы используем прототипное наследование JavaScript и OLOO — Objects Linking to Other Objects для создания объектов с общим прототипом. Сам прототип — это просто объект JavaScript, а не класс в прямом смысле этого слова. Отличное объяснение наследования в Javascript и его отличий от классического наследования можно найти в статье Эрика Эллиота здесь.
Давайте углубимся в код.

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

Перво-наперво, давайте создадим папку. Мы можем назвать это javascript-design-patterns в этой папке, мы создадим фабричную папку.
Фабричный паттерн в действии

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

В папке factory создадим файл Laptop.js.

const Laptop = function({ ram, hdd, name }) {
  this.ram = ram || 0;
  this.hdd = hdd || 0;
  this.name = name || "";
};

module.exports = Laptop;

В этом файле мы создаем функцию конструктора ноутбука. Он принимает объект в качестве параметра с атрибутами для создания экземпляра объекта с различными характеристиками, которые мы хотим захватить — в данном случае это размер ОЗУ, размер жесткого диска и имя устройства.
После этого мы экспортируем из модуля функцию-конструктор Laptop.

Давайте создадим еще один файл с именем table.js.

Мы сделаем то же самое, но со спецификациями, более подходящими для планшета.

const Tablet = function({ ram, hdd, name, network }) {
    this.ram = ram || 0;
    this.hdd = hdd || 0;
    this.network = network || 0;
    this.name = name || "";
};

module.exports = Tablet;

Теперь, когда у нас есть наши конструкторы, давайте создадим фабричную функцию, которая будет предоставлять API для создания новых экземпляров этих элементов. Добавьте новый файл с именем gadgetFactory.js.

const Laptop = require("./laptop");
const Tablet = require("./tablet");
const gadget = { Laptop, Tablet };

module.exports = {
    createGadget(type, attributes) {
        const GadgetType = gadget[type];
        return new GadgetType(attributes);
    }
};

Здесь мы начинаем с импорта конструкторов для создания объектов Laptop и Tablet. Затем мы создаем объект гаджета, используя имена конструкторов в качестве ключей. Это позволяет нам получить доступ к типу конструктора, который мы хотим, с помощью гаджета.[type]- где в этом примере тип будет «Ноутбук» или «Планшет».

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

Следует отметить, что когда мы вызываем функцию с ключевым словом new в Javascript, мы получаем взамен пустой объект с привязкой this, установленной на ту, что находится в выполняемой функции. Этот уникальный вызов также создаст прототипную связь между функцией-конструктором и любыми новыми объектами, которые мы создаем таким образом. Мы увидим это подробно в других шаблонах проектирования, которые мы рассмотрим.

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

Теперь мы можем создать файл, который будет использовать (или потреблять) API нашего заводского шаблона.

Создайте файл index.js и добавьте следующий код.

const gadgetFactory = require("./gadgetFactory");
const myLaptop = gadgetFactory.createGadget("Laptop", {
    ram: 8,
    ssd: 256,
    name: "Bab's MacBook Pro"
});

const myTablet = gadgetFactory.createGadget("Tablet", {
    ram: 4,
    hdd: 128,
    name: "Bab's iPad",
    network: '4G'
});

console.log(myLaptop);
console.log(myTablet);

Первое, что вы можете заметить, это то, что в этом файле нам не нужны конструкторы для ноутбуков и планшетов напрямую. Все, что нам нужно, это модуль gadgetFactory (с его методом createGadget). Используя этот метод, мы затем создаем два экземпляра ноутбука и планшета соответственно и выводим их на консоль.

Теперь в вашем терминале перейдите в папку javascript-design-patterns и введите:

$ node ./factory/index.js

Вы должны увидеть следующее, зарегистрированное в консоли:

Laptop { ram: 8, ssd: 256, name: 'Bab\'s MacBook Pro' }
Tablet { ram: 4, hdd: 128, network: '4G', name: 'Bab\'s iPad' }

Как видите, мы создали один тип объекта «Ноутбук» и один тип «Планшет», каждый со своими спецификациями. Используя этот шаблон, вы можете создать столько объектов гаджетов, сколько вам нужно, каждый со своими характеристиками.

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

В этом примере мы использовали функции-конструкторы Javascript, но этот шаблон также можно реализовать с помощью прототипов.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *