Слайды для лекции о паттернах, что я давал в Aller Media Norge в 2019.
Ссылка на исходник на GDocs:
https://docs.google.com/presentation/d/1CL2umKOcEeBehJ_hFlaD7P5pdoey_trCTeSnd5TiBSI/edit?usp=sharing
3. Kent & Ward, 1987
Kent Beck Howard Cunningham
Using Pattern Languages for
Object-Oriented Programs
OOPSLA-87
Origins & history
4. Gang of Four, 1995
Erich Gamma Richard Helm
Ralph Johnson John Vlissides
Origins & history
5. Вынесение семейства алгоритмов (аспектов, поведений) из
некоторого комплексного контекста в отдельные классы с целью
их взаимозаменяемости.
Также известен как Стратегия.
GoF Behavioral
Software design patterns
11. Определяет интерфейс для создания объектов, но предоставляет
подклассам принимать решение о типе создаваемого объекта.
Решает проблему зависимости клиентского кода от конкретных
типов создаваемых объектов.
GoF Creational
Software design patterns
12. Используем Фабрики когда
➔ контекст создаёт объекты
➔ разных (полиморфных) типов;
➔ возможно, сразу нескольких;
➔ у процесса создания есть зависимости, не
нужные в самом Контексте.
Предпосылки Эффекты
factory
17. Скрывает детали логики создания объекта за абстракцией шагов, тем самым позволяет
изменять некоторые шаги создания, как и сам тип создаваемого объекта.
Разделяет процесс конструирования и внутреннее устройство объектов.
Удобен для создания Композитов.
GoF Creational
Software design patterns
18. Нанимаем Билдера когда
➔ конструируем Композиты;
➔ в Контексте есть лишние
зависимости от внутреннего
устройства Продукта;
➔ список аргументов конструктора
стал слишком длинным.
Предпосылки Эффекты
builder
20. Контекст создает экземпляры Билдера и Директора, конфигурирует второго первым.
Директор реализует некоторый вариант процесса конструирования Продукта,
используя интерфейс Билдера для производства компонентов Продукта.
В простых случаях Контекст может брать на себя функции Директора.
Взаимодействия и варианты
builder
21. Фабрика обычно просто предоставляет готовый Продукт, тогда как Билдер позволяет
его конфигурировать и тоньше управлять процессом создания.
Фабрика отвечает на вопрос “Что?”, а Билдер — на вопрос “Как?”.
Фабрика самодостаточна, Билдеру нужен прораб (Директор).
Фабрики могут быть реализованы на основе Билдеров.
Как, впрочем, и наоборот.
Отличия от Фабрик
builder
24. Позволяет убедиться, что всегда существует только один
экземпляр класса, и предоставить глобальную точку доступа к
нему.
GoF Creational
Software design patterns
25. Синглтон идёт в дело когда
➔ мы заблуждаемся на счёт того, что
нам всегда будет достаточно одного
экземпляра класса;
➔ необходимо подменять этот
экземпляр объектами производных
типов.
Предпосылки Эффекты
singleton
26. Точка доступа к телу Синглтона может быть как статическим методом в классической
реализации, так и отдельной функцией (make()/app() в Laravel).
В некоторых языках (Typescript) допустимо возвращать производные типы из
конструкторов базовых, что делает возможным сокрытие доступа за обычным
оператором new.
Взаимодействия и варианты
builder
27. Синглтон ригиден.
Решение: полиморфизм и Dependency Injection в том или ином виде.
Синглтоны иногда перестают быть синглтонами.
Там где было одно соединение с БД, может появиться ещё одно для параллельных
запросов.
Там где был один DOM, когда-нибудь появится Shadow DOM.
Где не было тестов, однажды они должны появиться, а вместе с ними и необходимость
реинициализации разных вещей, в т.ч. и синглтонов.
Решение: полумеры вроде Multiton, либо не использовать синглтоны вообще, а
использовать какие-то пулы объектов.
Проблемы и их решения
singleton
28. Механизм уведомления о событиях в приложении, с низкой
связностью.
GoF Behavioral
Software design patterns
29. Используем Обсервер когда
➔ когда нужно организовать
отношение “многие ко многим”
между частями приложения,
➔ и когда структурой этих
зависимостей нужно управлять в
рантайме.
➔ Также для вынесения сайд-
эффектов BL (той её части, что не
нужна немедленно для получения
результата) (SRP).
Предпосылки Эффекты
observer
32. Классический Обсервер отягощён прямой зависимостью Обсервера от Субъекта, и
потому ограничен лишь отношением “один ко многим”.
Это исправляется через DIP — введение промежуточной сущности (События) и
зависимостью Субъекта и Обсервера от него, что позволяет получить отношение
“многие ко многим”, и, в итоге, систему, известную нам как PubSub или Event Emitter.
Диспетчер — может быть как Синглтоном, так и неотъемлемой частью Субъекта.
Не во всех языках и средах возможна передача информации о типе через Диспетчер,
потому приходится либо откатываться на “event.type” & “event.data as any”, либо
использовать классический, строго типизированный Обсервер.
Взаимодействия и варианты
observer