# OTUS ## Javascript Basic ## Вопросы? ## Связь модулей - от интерфейсов до EventBus ### Разберемся с задачей Для начала два термина - **связность(_cohesion_)** и **связанность(_coupling_)**. [Связность](
) - на сколько составные части направлены на решение одной задачи. [Связанность](
) - на сколько одни модули зависят от других (и как много они знают друг о друге) [Качественный дизайн обладает слабой связанностью (low coupling) и сильной связностью (high cohesion).](https://medium.com/german-gorelkin/low-coupling-high-cohesion-d36369fb1be9) Это значит, что программный компонент имеет небольшое число внешних связей и отвечает за решение близких по смыслу задач. **Слабое зацепление (Low Coupling)** и **Высокая связность (High Cohesion)** это 2 из 9 [**шаблонов GRASP**](
) Высокая связность говорит об эффективности программы (или ее отдельных модулей). Низкая связанность означает легкость рефакторинга и переиспользуемость кода. ### Вопросы? ### Наблюдатель (Observer) [Наблюдатель](https://refactoring.guru/ru/design-patterns/observer) - подход (паттерн), позволяющий одним объектам следить и реагировать на события, происходящие в других объектах.
На самом деле вы с ним уже работали - это [EventTarget](https://developer.mozilla.org/ru/docs/Web/API/EventTarget) Данный шаблон часто применяют в ситуациях, в которых отправителя сообщений не интересует, что делают получатели с предоставленной им информацией. Может быть представлен как ```ts IObservable { addObserver(event, handler) removeObserver(event, handler) notifyObserver(event, data) } ``` или ```ts EventTarget { addEventListener(event, handler) removeEventListener(event, handler) dispatchEvent(event) } ``` или ```ts Backbone.Events { on(event, handler) off(event, handler) trigger(event) } ``` Иногда могут добавлять вспомогательные методы, например ```ts Backbone.Events { // ... once(event, handler) } ``` ```ts document.querySelector(element).addEventListener("click", (ev) => { alert("Boom!"); }); ``` Оговорка: чаще всего обработчиком события является функция. Но это также может быть и объект ([EventListener](https://developer.mozilla.org/ru/docs/Web/API/EventListener)) - в зависимости от реализации. ### Вопросы? ### Посредник (Mediator) [Посредник](https://refactoring.guru/ru/design-patterns/mediator) - это поведенческий паттерн проектирования, который позволяет уменьшить связанность множества классов между собой, благодаря перемещению этих связей в один класс-посредник. **Задача:** Обеспечить взаимодействие множества объектов, сформировав при этом слабую связанность и избавив объекты от необходимости явно ссылаться друг на друга. **Решение:** Создать объект, инкапсулирующий способ взаимодействия множества объектов. **Преимущества:** Устраняется связанность между "Коллегами", централизуется управление. Самый распространенный (и простой) вариант реализации паттерна - с использованием **EventEmitter** интерфейса (**Event Bus** - Шина событий). Разница, по сравнению с обычным использованием EventTarget: - события в EventTarget генерирует сам объект, при работе с EventBus это делают сторонние объекты - список событий при работе с EventTarget ограничен устройством объекта, при работе с EventBus он определяется участниками
При этом, чтобы избежать коллизии имен событий, зачастую вводят `namespaces`, в формате **{NAMESPACE}:{EVENT NAME}**. Например `user:add`, `searchHistory:add`. Нужно отметить, что по-хорошему, префиксы делаются на основе сущностей, а не на основе модулей (иначе происходит раскрытие структуры системы). ```ts const eventBus = new EventBus(); // module 1 eventBus.on("city:changed", (cityName) => console.log(`New city: ${cityName}`)); // module 2 eventBus.trigger("city:changed", "Minsk"); ``` Как мы могли бы применить это к уже сделанным домашним заданиям? ### Вопросы? ### Практика [Реализовать Event Emitter](https://codesandbox.io/s/github/vvscode/otus--javascript-basic/tree/master/lessons/lesson33/code/eventEmitter) Реализовать поверх существующего функционала метод **once** (для одноразового вызова обработчика). ### Вопросы? Дополнительные материалы: - [Backbone Events](https://backbonejs.org/#Events) и [исходники](https://backbonejs.org/docs/backbone.html#section-17) - [EventTarget simple implementation](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) - [Паттерны проектирования понятным языком](https://refactoring.guru/ru/design-patterns) - [Design patterns for humans!](https://github.com/sohamkamani/javascript-design-patterns-for-humans) ### Опрос о занятии