322 просмотра
От 7 октября 2023

Раскрытие на примерах почти всех паттернов проектирования

1. Что такое шаблон проектирования?

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

2. Группы шаблонов проектирования

Шаблоны проектирования делятся на три группы: 1. Порождающие - описывают создание объекта (instantiation) или группы связанных объектов. 2. Структурные - в основном посвящены компоновке объектов (object composition). То есть тому, как сущности могут друг друга использовать. 3. Поведенченские - связаны с присвоением обязанностей (responsibilities) объектам. От структурных шаблонов они отличаются тем, что не просто описывают структуру, но и очерчивают шаблоны передачи данных, обеспечения взаимодействия.

3. Порождающие шаблоны

Вкратце Порождающие шаблоны описывают создание (instantiate) объекта или группы связанных объектов. Википедия В программной инженерии порождающими называют шаблоны, которые используют механизмы создания объектов, чтобы создавать объекты подходящим для данной ситуации способом. Базовый способ создания может привести к проблемам в архитектуре или к её усложнению. Порождающие шаблоны пытаются решать эти проблемы, управляя способом создания объектов. - Простая фабрика - Фабричный метод - Абстрактная фабрика - Строитель - Прототип - Одиночка

4. Простая фабрика

Аналогия Допустим, вы строите дом и вам нужны двери. Будет бардак, если каждый раз, когда вам требуется дверь, вы станете вооружаться инструментами и делать её на стройплощадке. Вместо этого вы закажете двери на фабрике. Вкратце Простая фабрика просто генерирует экземпляр для клиента без предоставления какой-либо логики экземпляра. Википедия В объектно ориентированном программировании фабрикой называется объект, создающий другие объекты. Формально фабрика — это функция или метод, возвращающая объекты разных прототипов или классов из вызова какого-то метода, который считается новым. Когда использовать? Когда создание объекта подразумевает какую-то логику, а не просто несколько присваиваний, то имеет смысл делегировать задачу выделенной фабрике, а не повторять повсюду один и тот же код. Пример Для начала нам нужен интерфейс двери и его реализация. interface Door { public function getWidth(): float; public function getHeight(): float; } class WoodenDoor implements Door { protected $width; protected $height; public function __construct(float $width, float $height) { $this->width = $width; $this->height = $height; } public function getWidth(): float { return $this->width; } public function getHeight(): float { return $this->height; } } Теперь соорудим фабрику дверей, которая создаёт и возвращает нам двери. class DoorFactory { public static function makeDoor($width, $height): Door { return new WoodenDoor($width, $height); } } Использование: $door = DoorFactory:makeDoor(100, 200); echo 'Width: ' . $door->getWidth(); echo 'Height: ' . $door->getHeight();

5. Фабричный метод

Аналогия Одна кадровичка не в силах провести собеседования со всеми кандидатами на все должности. В зависимости от вакансии она может делегировать разные этапы собеседований разным сотрудникам. Вкратце Это способ делегирования логики создания объектов (instantiation logic) дочерним классам. Википедия В классо-ориентированном программировании (class-based programming) фабричным методом называют порождающий шаблон проектирования, использующий генерирующие методы (factory method) для решения проблемы создания объектов без указания для них конкретных классов. Объекты создаются посредством вызова не конструктора, а генерирующего метода, определённого в интерфейсе и реализованного дочерними классами либо реализованного в базовом классе и, опционально, переопределённого (overridden) производными классами (derived classes). Когда использовать? Этот шаблон полезен для каких-то общих обработок в классе, но требуемые подклассы динамически определяются в ходе выполнения (runtime). То есть когда клиент не знает, какой именно подкласс может ему понадобиться. Пример Сначала создадим интерфейс сотрудника, проводящего собеседование, и некоторые реализации для него. interface Interviewer { public function askQuestions(); } class Developer implements Interviewer { public function askQuestions() { echo 'Asking about design patterns!'; } } class CommunityExecutive implements Interviewer { public function askQuestions() { echo 'Asking about community building'; } } Теперь создадим кадровичку HiringManager. abstract class HiringManager { // Фабричный метод abstract public function makeInterviewer(): Interviewer; public function takeInterview() { $interviewer = $this->makeInterviewer(); $interviewer->askQuestions(); } } Любой дочерний класс может расширять его и предоставлять нужного собеседующего: class DevelopmentManager extends HiringManager { public function makeInterviewer(): Interviewer { return new Developer(); } } class MarketingManager extends HiringManager { public function makeInterviewer(): Interviewer { return new CommunityExecutive(); } } Использование: $devManager = new DevelopmentManager(); $devManager->takeInterview(); // Output: Спрашивает о шаблонах проектирования. $marketingManager = new MarketingManager(); $marketingManager->takeInterview(); // Output: Спрашивает о создании сообщества.

6. Абстрактная фабрика

Аналогия Вернёмся к примеру с дверями из «Простой фабрики». В зависимости от своих потребностей вы можете купить деревянную дверь в одном магазине, стальную — в другом, пластиковую — в третьем. Для монтажа вам понадобятся разные специалисты: деревянной двери нужен плотник, стальной — сварщик, пластиковой — спец по ПВХ-профилям. Вкратце Это фабрика фабрик. То есть фабрика, группирующая индивидуальные, но взаимосвязанные/взаимозависимые фабрики без указания для них конкретных классов. Википедия Шаблон «Абстрактная фабрика» описывает способ инкапсулирования группы индивидуальных фабрик, объединённых некой темой, без указания для них конкретных классов. Когда использовать? Когда у вас есть взаимосвязи с не самой простой логикой создания (creation logic). Пример interface DoorFactory { public function makeDoor(): Door; public function makeFittingExpert(): DoorFittingExpert; } // Фабрика деревянных дверей возвращает плотника и деревянную дверь class WoodenDoorFactory implements DoorFactory { public function makeDoor(): Door { return new WoodenDoor(); } public function makeFittingExpert(): DoorFittingExpert { return new Carpenter(); } } // Фабрика стальных дверей возвращает стальную дверь и сварщика class IronDoorFactory implements DoorFactory { public function makeDoor(): Door { return new IronDoor(); } public function makeFittingExpert(): DoorFittingExpert { return new Welder(); } } Использование: $woodenFactory = new WoodenDoorFactory(); $door = $woodenFactory->makeDoor(); $expert = $woodenFactory->makeFittingExpert(); $door->getDescription(); // Output: Я деревянная дверь $expert->getDescription(); // Output: Я могу устанавливать только деревянные двери // Same for Iron Factory $ironFactory = new IronDoorFactory(); $door = $ironFactory->makeDoor(); $expert = $ironFactory->makeFittingExpert(); $door->getDescription(); // Output: Я стальная дверь $expert->getDescription(); // Output: Я могу устанавливать только стальные двери

7. Строитель

Аналогия Допустим, вы пришли в забегаловку, заказали бургер дня, и вам выдали его без вопросов. Это пример «Простой фабрики». Но иногда логика создания состоит из большего количества шагов. К примеру, при заказе бургера дня есть несколько вариантов хлеба, начинки, соусов, дополнительных ингредиентов. В таких ситуациях помогает шаблон «Строитель». Вкратце Шаблон позволяет создавать разные свойства объекта, избегая загрязнения конструктора (constructor pollution). Это полезно, когда у объекта может быть несколько свойств. Или когда создание объекта состоит из большого количества этапов. Википедия Шаблон «Строитель» предназначен для поиска решения проблемы антипаттерна Telescoping constructor. Поясню, что такое антипаттерн Telescoping constructor. Каждый из нас когда-либо сталкивался с подобным конструктором: public function __construct( $size, $cheese = true, $pepperoni = true, $tomato = false, $lettuce = true ) Как видите, количество параметров может быстро разрастись, и станет трудно разобраться в их структуре. Кроме того, этот список параметров будет расти и дальше, если в будущем вы захотите добавить новые опции. Это и есть антипаттерн Telescoping constructor. Когда использовать? Когда у объекта может быть несколько свойств и когда нужно избежать Telescoping constructor. Ключевое отличие от шаблона «Простая фабрика»: он используется в одноэтапном создании, а «Строитель» — в многоэтапном. Пример Сначала создадим бургер: class Burger { protected $size; protected $cheese = false; protected $pepperoni = false; protected $lettuce = false; protected $tomato = false; public function __construct(BurgerBuilder $builder) { $this->size = $builder->size; $this->cheese = $builder->cheese; $this->pepperoni = $builder->pepperoni; $this->lettuce = $builder->lettuce; $this->tomato = $builder->tomato; } } А затем добавим «строителя»: class BurgerBuilder { public $size; public $cheese = false; public $pepperoni = false; public $lettuce = false; public $tomato = false; public function __construct(int $size) { $this->size = $size; } public function addPepperoni() { $this->pepperoni = true; return $this; } public function addLettuce() { $this->lettuce = true; return $this; } public function addCheese() { $this->cheese = true; return $this; } public function addTomato() { $this->tomato = true; return $this; } public function build(): Burger { return new Burger($this); } } Использование: $burger = (new BurgerBuilder(14)) ->addPepperoni() ->addLettuce() ->addTomato() ->build();

8. Прототип

Поддержите проект и получите доступ ко всему контенту всего за 290

9. Одиночка

Поддержите проект и получите доступ ко всему контенту всего за 290

10. Структурные шаблоны

Поддержите проект и получите доступ ко всему контенту всего за 290

11. Адаптер

Поддержите проект и получите доступ ко всему контенту всего за 290

12. Мост.

Поддержите проект и получите доступ ко всему контенту всего за 290

13. Компоновщик

Поддержите проект и получите доступ ко всему контенту всего за 290

14. Декоратор

Поддержите проект и получите доступ ко всему контенту всего за 290

15. Фасад

Поддержите проект и получите доступ ко всему контенту всего за 290

16. Приспособленец

Поддержите проект и получите доступ ко всему контенту всего за 290

17. Заместитель

Поддержите проект и получите доступ ко всему контенту всего за 290

18. Поведенченские шаблоны

Поддержите проект и получите доступ ко всему контенту всего за 290

19. Цепочка ответственности

Поддержите проект и получите доступ ко всему контенту всего за 290

20. Команда

Поддержите проект и получите доступ ко всему контенту всего за 290

21. Итератор

Поддержите проект и получите доступ ко всему контенту всего за 290

22. Посредник

Поддержите проект и получите доступ ко всему контенту всего за 290

23. Хранитель

Поддержите проект и получите доступ ко всему контенту всего за 290

24. Наблюдатель

Поддержите проект и получите доступ ко всему контенту всего за 290

25. Посетитель

Поддержите проект и получите доступ ко всему контенту всего за 290

26. Стратегия

Поддержите проект и получите доступ ко всему контенту всего за 290

27. Состояние

Поддержите проект и получите доступ ко всему контенту всего за 290

28. Шаблонный метод

Поддержите проект и получите доступ ко всему контенту всего за 290
Хотите стать частью сообщества Девстанции?
Вступайте в наш чат в Telegram

Также в этой категории

Шпаргалка
  11 вопросов

HTTP, SSL, WebSocket и прочее

Вопросы для собеседования бэкенд-разработчика

302 просмотра
От 12 октября 2023
Шпаргалка
  13 вопросов

Общие принципы и понятия ООП

Вопросы для собеседования по теме ООП

255 просмотров
От 7 октября 2023
Шпаргалка
  15 вопросов

Шпаргалка по Domain-Driven Design

Вопросы и ответы про предметно-ориентированное проектирование

234 просмотра
От 27 января
Шпаргалка
  12 вопросов

Операционные системы: базовые понятия

Потоки, процессы, конкурентность и прочие понятия из мира ОС

256 просмотров
От 27 января

Вам может быть интересно

Шпаргалка
  11 вопросов

Теория шардинга баз данных

О распределении данных между серверами

314 просмотров
От 10 октября 2023
Шпаргалка
  7 вопросов

Коллекция полезных команд для Docker

Большая шпаргалка по всем командам Docker

266 просмотров
От 12 октября 2023
Шпаргалка
  10 вопросов

Всё о репликации баз данных

Описание понятий и процессов репликации БД

269 просмотров
От 8 октября 2023
Шпаргалка
  60 вопросов

60 вопросов про базы данных и SQL

Вопросы и ответы с собеседования по базам данных и SQL

413 просмотров
От 20 февраля

Топ тредов

Gravatar for 9tokio
Tokio:
то что раньше было бесплатным теперь платное - вот это я понимаю

Последнее сообщение:
Логотип Девстанции
Девстанция:
Спасибо за поддержку проекта :) Повышение качества контента - один из важнейших приоритетов. Этому м...
3 сообщения
270 просмотров

Логотип Девстанции
Девстанция:
Поиск людей для совместной разработки IT-стартапов

Последнее сообщение:
В этом треде пока нет сообщений
0 сообщений
141 просмотр

Логотип Девстанции
Девстанция:
Какой язык программирования выбрать в качестве первого?

Последнее сообщение:
Gravatar for 2kokke
Kokke:
Python или JS - универсально. Но по уму надо бы с чего-то строгого начинать и достаточно низкоуровне...
1 сообщение
176 просмотров

Все категории