Шаблони дизайну JavaScript Частина 1: Заводський зразок

Фото Патріка Хендрі на знімку

Останнім часом, коли проекти, над якими я мав можливість працювати, набули масштабу, я забирав час глибше заглиблюватися в шаблони дизайну для написання більш доступного та масштабованого коду Javascript. Шаблони дизайну - це прекрасний спосіб застосувати випробувані часом та бойовими рішеннями поширені проблеми, щоб ми могли швидше та ефективніше їх вирішити.

Більшість зразків дизайну, які ми будемо висвітлювати, базуються на об'єктно-орієнтованому програмуванні, і як таке, має сенс, що ми починаємо з розгляду творчого малюнка, так званого, тому що цей шаблон забезпечує нам чіткий інтерфейс для створення об'єктів під час абстрагування різноманітна складність або логіка, що бере участь у їх створенні. Цей візерунок називається заводським малюнком, і він дозволяє нам легко створювати об'єкти в JavaScript.

Походячи з інших мов на основі класів OOP, можна спокуситись думати, що те, що ми будемо робити у рядках коду нижче, - це створення класів і примірників, але насправді це лише синтаксичний цукор, зроблений так, щоб виглядати як синтаксис з класу заснована мова.

Насправді ми використовуємо наслідування прототипів JavaScript та OLOO - об’єкти, що пов'язують інші об'єкти, щоб створити об'єкти із спільним прототипом. Сам прототип - це просто звичайний об’єкт JavaScript, а не клас у справжньому сенсі цього слова. Чудове пояснення успадкування у Javascript та його відмінності від класичного успадкування можна знайти у статті Еріка Еліота тут.

Давайте зануримось у якийсь код.

Усі приклади з цієї серії будуть доступні на Github тут і містять інструкції, як запустити код.

Для запуску коду в цій статті вам потрібно встановити Node на вашій машині. Дотримуйтесь цих вказівок, якщо у вас їх ще немає. Якщо ви рухаєтесь разом із репо, ви знайдете вказівки щодо запуску коду в readme.

Спочатку спочатку створимо папку. У цій папці ми можемо назвати шаблони javascript-design, ми створимо заводську папку.

Заводський зразок в дії

Заводський шаблон обгортає конструктор для різних типів об'єктів і повертає екземпляри об'єктів за допомогою простого API. Це дозволяє легко створювати різні об'єкти, відкриваючи простий API, який повертає вказаний тип об'єкта.

Почнемо із створення наших конструкторів. Ці функції відповідають за повернення нових об'єктів певного типу при виклику.

У заводській папці створимо файл laptop.js.

const Ноутбук = функція ({ram, hdd, name}) {
  this.ram = таран || 0;
  this.hdd = hdd || 0;
  this.name = ім'я || "";
};
module.exports = Ноутбук;

У цьому файлі ми створюємо функцію конструктора ноутбука. Він приймає об'єкт як параметр з атрибутами для інстанціфікації об'єкта з різними специфікаціями, які ми хочемо захопити - у цьому випадку розмір оперативної пам’яті, розмір жорсткого диска та назва пристрою.

Після цього ми експортуємо функцію конструктора ноутбука з модуля.

Створимо інший файл під назвою tablet.js

Ми зробимо те ж саме, але із специфікаціями, більш релевантними планшетному ПК.

const Tablet = функція ({ram, hdd, ім'я, мережа}) {
    this.ram = таран || 0;
    this.hdd = hdd || 0;
    this.network = мережа || 0;
    this.name = ім'я || "";
};
module.exports = Планшет;

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

const Ноутбук = вимагати ("./ ноутбук");
const Tablet = вимагати ("./ планшет");
const gadget = {Ноутбук, планшет};
module.exports = {
    createGadget (тип, атрибути) {
        const GadgetType = гаджет [тип];
        повернути новий GadgetType (атрибути);
    }
};

Тут ми почнемо з імпорту конструкторів для створення об’єктів Ноутбук та Планшет. Потім ми створюємо об’єкт гаджета, використовуючи в якості ключів імена конструктора. Це дає нам можливість отримати тип конструктора, який ми хочемо, використовуючи гаджет [type] - де в цьому прикладі тип буде або "Ноутбук" або "Планшет". Нарешті, ми експортуємо об'єкт із цього модуля методом createGadget. Цей метод приймає тип ґаджета як перший параметр і викликає вказаний тип конструктора, передаючи в ньому атрибути.

Ви повинні зауважити, що коли ми викликаємо функцію з новим ключовим словом у Javascript, ми отримуємо взамін порожній об’єкт із цим набором прив'язки до того, який виконується у функції виконання. Цей унікальний виклик також створить прототипний зв'язок між функцією конструктора та будь-якими новими об'єктами, які ми створюємо таким чином. Це ми детально побачимо в інших моделях дизайну, які ми покриємо.

Також варто зазначити, що перша літера з великої літери - це лише умова, а не вимога. Це не робить нічого особливого, і ми могли так само добре назвати функції з camelCase, як це зазвичай робимо з іншими назвами змінних та функцій у JavaScript.

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

Створіть файл index.js і додайте наступний код.

const gadgetFactory = вимагати ("./ gadgetFactory");
const myLaptop = gadgetFactory.createGadget ("Ноутбук", {
    таран: 8,
    ssd: 256,
    назва: "MacBook Pro Баба"
});
const myTablet = gadgetFactory.createGadget ("Планшет", {
    таран: 4,
    hdd: 128,
    назва: "Бабський iPad",
    мережа: '4G'
});
console.log (мій ноутбук);
console.log (myTablet);

Перше, що ви можете помітити, це те, що в цьому файлі нам не потрібні конструктори для ноутбуків та планшетів безпосередньо. Все, що нам потрібно, - це модуль gadgetFactory (з його методом createGadget). За допомогою цього методу ми створюємо два екземпляри ноутбука та планшета відповідно та виходимо на консоль.

Тепер у своєму терміналі перейдіть до папки javascript-design-pattern і введіть:

$ node ./factory/index.js

На консолі ви повинні побачити наступне:

Ноутбук {ram: 8, ssd: 256, name: 'Bab \' s MacBook Pro '}
Планшет {ram: 4, hdd: 128, мережа: '4G', назва: 'Bab \' s iPad '}

Як бачите, ми створили один тип об’єкта ноутбука, а також тип планшета, кожен з яких має свої специфікації. За допомогою цього шаблону ви можете створити стільки об’єктів гаджетів, скільки вам потрібно, зі своїми специфікаціями.

І це все за заводським зразком. Це, звичайно, спрощена реалізація, і в будь-якому іншому, окрім тривіального додатка, ви напевно хочете включити більш жорстку логіку - наприклад, навколо ваших конструкторів.

У цьому прикладі ми використовували конструкторські функції Javascript, але ця модель також може бути реалізована за допомогою прототипів. Ми вивчимо це в наступній статті, коли будемо переробляти код, щоб зробити його більш ефективним.

Далі в серії ми будемо висвітлювати популярний шаблон видавця / передплатників (або коротко PubSub). Щоб залишатись сповіщеним, не забудьте прописати мене, і якщо ви вважаєте цю статтю корисною, залишайте великі пальці (або 5 ). Як завжди, я хотів би почути ваші думки в коментарях нижче!

Оновлення: Частину 2 серії, що охоплює шаблон видавця / підписника, ви можете знайти тут.

Babs - розробник JavaScript, який вдень пише React / React Native & NodeJS (із здоровою дозою GraphQL), а все інше - JavaScript під прикриттям ночі. Ви можете знайти його у Twitter та Instagram, де він ділиться деталями свого підпільного кохання з JavaScript.