Skip to content

Latest commit

 

History

History
225 lines (132 loc) · 7.88 KB

File metadata and controls

225 lines (132 loc) · 7.88 KB
title Занятие 25
description Связь модулей - от интерфейсов до EventBus

OTUS

Javascript Basic

Вопросы?

Связь модулей - от интерфейсов до EventBus

Разберемся с задачей

Для начала два термина - связность(cohesion) и связанность(coupling).

Связность - на сколько составные части направлены на решение одной задачи.

Связанность - на сколько одни модули зависят от других (и как много они знают друг о друге)

Качественный дизайн обладает слабой связанностью (low coupling) и сильной связностью (high cohesion).

Это значит, что программный компонент имеет небольшое число внешних связей и отвечает за решение близких по смыслу задач.

Слабое зацепление (Low Coupling) и Высокая связность (High Cohesion) это 2 из 9 шаблонов GRASP

Высокая связность говорит об эффективности программы (или ее отдельных модулей).

Низкая связанность означает легкость рефакторинга и переиспользуемость кода.

Вопросы?

Наблюдатель (Observer)

Наблюдатель - подход (паттерн), позволяющий одним объектам следить и реагировать на события, происходящие в других объектах.

На самом деле вы с ним уже работали - это EventTarget

Данный шаблон часто применяют в ситуациях, в которых отправителя сообщений не интересует, что делают получатели с предоставленной им информацией.

Может быть представлен как

IObservable {
  addObserver(event, handler)
  removeObserver(event, handler)
  notifyObserver(event, data)
}

или

EventTarget {
  addEventListener(event, handler)
  removeEventListener(event, handler)
  dispatchEvent(event)
}

или

Backbone.Events {
  on(event, handler)
  off(event, handler)
  trigger(event)
}

Иногда могут добавлять вспомогательные методы, например

Backbone.Events {
  // ...
  once(event, handler)
}
document.querySelector(element).addEventListener("click", (ev) => {
  alert("Boom!");
});

Оговорка: чаще всего обработчиком события является функция. Но это также может быть и объект (EventListener) - в зависимости от реализации.

Вопросы?

Посредник (Mediator)

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

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

Решение: Создать объект, инкапсулирующий способ взаимодействия множества объектов.

Преимущества: Устраняется связанность между "Коллегами", централизуется управление.

Самый распространенный (и простой) вариант реализации паттерна - с использованием EventEmitter интерфейса (Event Bus - Шина событий).

Разница, по сравнению с обычным использованием EventTarget:

  • события в EventTarget генерирует сам объект, при работе с EventBus это делают сторонние объекты
  • список событий при работе с EventTarget ограничен устройством объекта, при работе с EventBus он определяется участниками

При этом, чтобы избежать коллизии имен событий, зачастую вводят namespaces, в формате {NAMESPACE}:{EVENT NAME}. Например user:add, searchHistory:add.

Нужно отметить, что по-хорошему, префиксы делаются на основе сущностей, а не на основе модулей (иначе происходит раскрытие структуры системы).

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

Реализовать поверх существующего функционала метод once (для одноразового вызова обработчика).

Вопросы?

Дополнительные материалы:

Опрос о занятии