Патерни проектування у сучасному JavaScript

7 хв. читання

Об'єктно-орієнтоване програмування намагається створити модель світу, що нас оточує. Тож є сенс використовувати навколишній світ як інструмент для опису розробки.

Якщо ми звернемося до книги «Мова патернів: міста, будівлі, будівництво», побачимо таку характеристику патерну:

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

У розробці ПЗ архітектура — процес створенння застосунку в правильний, надійний і доступний спосіб. Патерни ж визначають типові шляхи, шаблони розв'язань поширених проблем. Вони можуть бути як абстрактними й концептуальними, так і дуже точними й технічними, це дозволяє розробникам порозумітися.

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

У статті оглянемо найпоширеніші патерни сучасних JavaScript проектів з більш формального боку.

«Одинак» (Singleton)

Як розуміти

Патерн Singleton найпопулярнішим не назвеш, але він відносно простий, тож почнемо саме з нього.

«Одинак» випливає з математичної концепції одиничної множини. Наприклад, множина {null} — одинична (singleton).

У розробці цей патерн обмежує створення екземпляра класу одним об'єктом. Тобто буде створено лише перший екземпляр класу, а всі наступні будуть повертати той самий об'єкт.

Патерни проектування у сучасному JavaScript
Навіщо нам два супергероя, якщо є Бетмен?

Навіщо

Які варіанти використання є у патерна Singleton, окрім того, що він дозволяє мати лише одного супергероя (яким, очевидно, буде Бетмен)?

Хоч в «Одинака» і є деякі проблемні моменти, його і досі використовують. Найбільш примітний варіант — створення конфігураційних об'єктів. Вам, імовірно, потрібен лише один такий об'єкт у застосунку, якщо, звичайно, ваша фіча не має декілька конфігурацій.

Де використовується

Сервіси Angular — яскравий приклад використання патерну «Одинак» у великому популярному фреймворку. В документації Angular є спеціальна сторінка з поясненнями, як переконатися, що сервіс завжди Singleton.

Справді, є сенс реалізовувати цей патерн у сервісах, адже вони використовуються для збереження стану, кофігурації і дозволяють компонентам взаємодіяти. Адже вам не треба, щоб додаткові екземпляри наводили безлад у концепції.

Як приклад розглянемо простий застосунок для підрахунку кількості натискань на кнопку:

Патерни проектування у сучасному JavaScript

Вам треба відстежувати кількість натискань на кнопку в одному об'єкті, який передбачає:

  • функціонал підрахунку;
  • поточну кількість кліків.

Якщо б цей об'єкт не був «одинаком» (тобто кожна кнопка мала б власний екземпяр), кількість кліків не була б правильною. До того ж, який би екземпляр ви використали у компоненті, щоб показати поточну кількість натискань?

«Спостерігач» (Observer)

Як розуміти

Observer — патерн проектування, за якого суб'єкт підтримує певну кількість своїх спостерігачів і повідомляє їх про будь-які зміни стану: зазвичай, викликаючи один з їхніх методів.

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

Зазвичай, якщо ви хочете придбати газету, то шукаєте газетний кіоск і запитуєте, чи є потрібний вам випуск. Якщо немає, ви з сумом йдете додому і потім повторюєте той самий процес. У термінах JavaScript це означало б циклічний обхід того самого коду, поки не буде досягнено потрібного результату.

Коли ж ви нарешті отримуєте бажану газету, це те ж саме, що виконати потрібну колбек-функцію у JavaScript.

Мудріше було було б підписатися на улюблену газету та отримувати кожен новий випуск. Більше ніяких походів до газетного кіоску. Більше ніяких розчарувань.

У термінах JavaScript: ви не будете пробігатися циклом, очікуючи на виклик функції. Ви вкажете суб'єкту, що вам потрібні певні події (повідомлення) , а колбек буде викликано, коли з'являться нові дані. У такому випадку ви — спостерігач.

Патерни проектування у сучасному JavaScript

Зручно, що у суб'єкта можуть бути одразу декілька підписників, які отримуватимуть сповіщення про події.

Навіщо

У шаблона «Спостерігач» достатньо варіантів використання. Як правило, він застосовується, коли треба реалізувати зв'язок «один до багатьох» між різними й не дуже тісно пов'язаними об'єктами, щоб мати можливість повідомити необмеженому числу об'єктів про зміну стану.

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

Імовірно, ви вже застосовували цей шаблон, якщо мали справу з addEventListener. Додавання слухача подій до елементу має всі ознаки шаблону «Спостерігач»:

  • можна підписатися на об'єкт;
  • можна відписатися від об'єкта;
  • об'єкт може передавати подію усім своїм підписникам.

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

Де використовується

Реалізувати базовий «Спостерігач» не буде складно, але існує вже готова бібліотека ReactiveX та аналог у JavaScript — RxJS.

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

Окрім патерна «Спостерігач», ReactiveX має реалізацію «Ітератора». З «Ітератором» суб'єкти можуть дізнатися про закінчення підписки і завершити її.

«Фасад» (Facade)

Як розуміти

Шаблон «Фасад» запозичив свою назву з архітектури, де:

Фасад — це, як правило, зовнішня сторона будівлі. Слово пішло від французького «façade», що означає «обличчя».

В архітектурі це екстерьєр будівлі, що приховує внутрішній вміст. У розробці ПЗ шаблон «Фасад» намагається приховати складність реалізації. Тобто ви працюєте лише зі зрозумілим API, водночас змінюючи код, як вам потрібно.

Навіщо

Шаблон Facade знадобиться вам багато де, але найбільш очевидне використання — приховування складності коду і максимальне послаблення залежностей.

Патерни проектування у сучасному JavaScript

Зображення вище повністю пояснює концепцію «Фасаду». Ви не хочете мати справу з драконами, якщо цього можна уникнути. Об'єкт «Фасад» передбачає API та взаємодіє з усіма драконами самостійно.

Тепер у вас є чудова можливість змінити дракона, не торкаючись решти застосунку. Припустимо, ви хочете перетворити дракона на кошеня. Для цього потрібно переписати коду «Фасаду» без модифікацій будь-яких залежних об'єктів.

Де використовується

Facade часто використовується в Angular у якості сервісів, що спрощують внутрішню логіку. Але це не обов'язково повинен бути Angular, як побачимо далі.

Припустимо, ви хочете додати до застосунку управління станом. Для цього можна використати Redux, NgRx, Akita, MobX, Apollo або будь-який інший популярний інструмент. Чому б не використати їх всіх одразу?

Який базовий функціонал повинна забезпечувати бібліотека управління станом?

Зазвичай, це:

  • спосіб сповіщення, що стан змінився;
  • спосіб отримання поточного (зрізу) стану.

Тепер, з усією могутністю шаблону, ви можете реалізувати «Фасади» для кожної частини стану, яка передбачатиме певне API для вашої роботи. Ви отримаєте прості для розуміння методи, на зразок facade.startSpinner(), facade.stopSpinner() та facade.getSpinnerState().

Після цього ви можете зайнятися реалізацією «Фасаду» і написати код, який працював би з Apollo (або з GraphQL ). Згодом ви помітите, що обрана бібліотека зовсім не підходить вашому проекту. Без проблем. Реалізуйте новий «Фасад», що підтримуватиме MobX.

Патерни проектування у сучасному JavaScript

Що далі

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

До речі, ось дві книги, які допоможуть вам глибше розібратися у шаблонах проектування:

  • Design Patterns: Elements of Reusable Object-Oriented Software (Erich Gamma, Richard Helm, Ralph Johnson, та John Vlisside (Банда чотирьох)) — книга претендує на звання Біблії шаблонів проектування ПЗ.
  • Head First Design Patterns (Bert Bates, Kathy Sierra, Eric Freeman та Elisabeth Robson) — легша для розуміння, намагається передати сенс патернів через візуальне сприйняття.

І не варто забувати про старий-добрий Google: читайте, пробуйте різні підходи та дізнавайтеся щось нове.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 3.9K
Приєднався: 11 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація