Паттерны — примеры из жизни

Шаблоны проектирования программного обеспечения уходят корнями в архитектурные шаблоны Кристофера Александера, и в вопросы перехода к объектам. Согласно Александеру, шаблоны повторяют самих себя, поскольку они являются обобщенным решением для задаваемой системы сил. Вопросы перехода к объектам рассматривается в реальном мире для того, чтобы проникнуть в суть взаимоотношений при моделировании программного обеспечения. С такими двойственными корнями, вполне логичным будет найти повторяемость шаблонов проектирования программного обеспечения в объектах реального мира. В этой статье представлен реальный мир, не программные экземпляры каждого шаблона проектирования из книги "Приемы объектно-ориентированного проектирования. Паттерны проектирования" [13]. В статье также приводятся выводы о не программных примерах как эффективной основе языка шаблонов для взаимообщения и обучения проектированию шаблонов.

Введение

В индустрии программного обеспечения существует растущее сообщество сторонников применения шаблонов. Корни перехода к шаблонам можно найти в работах архитектора Кристофера Александера, который описывал шаблоны как обобщенное решение для задаваемой системы сил в мире [1]. Шаблоны Александера можно обнаружить в повседневных структурах. Каждый из шаблонов в "Языке шаблонов" [2], включает в себя картину архетипического примера шаблона.

Поскольку объекты были преобладающим взглядом на мир в то время, когда мир программного обеспечения знакомился с шаблонами, они тоже имеют корни в переходе к объектам [9]. К сожалению примеров шаблонов моделирования программного обеспечения было не так много как у Александера, а они представляли собой более элегантные модели, в отличие от моделей, что люди генерировали в самом начале [13]. Доступ к элегантным моделям часто ограничивался в связи с проприетарным характером большей части программного обеспечения, разработанного сегодня.

Согласно Александеру, реальный мир шаблонов всегда повторяет самого себя, поскольку в соответствии с заданным набором обстоятельств, всегда существует определенные поля взаимосвязей, которые являются наиболее хорошо приспособленными к силам, которые уже существуют [1]. В программном обеспечении, задачи реального мира либо моделируются целиком, либо объекты реального мира сводят к аппаратному программному обеспечению, а программы выводят результаты реального мира [5]. Поскольку шаблоны моделирования программного обеспечения имеют корни как в шаблонах Александера, так и в вопросах перехода к объектам, представляется вполне логичным, что шаблоны моделирования программного обеспечения могут быть найдены и в объектах реального мира. Это не означает, что шаблонам моделирования программного обеспечения необходимы модели объектов реального мира, но взаимосвязи между объектами, которые приспособлены для работы с определенными силами, могут быть обнаружены как в "реальном мире", так и в объектах программного обеспечения. Чтобы проверить эту гипотезу, были найдены примеры из реального мира для каждого из 23 шаблонов "Банды Четырех" [13]. Эти примеры приводятся далее в разделах со 2 по 4.

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

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

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

Целью "Абстрактной фабрики" является предоставление интерфейса для создания семейств связанных объектов, без указания конкретных классов. Этот шаблон можно соотнести с оборудованием для штамповки из листового металла, используемого при производстве японских автомобилей. Штамповочное оборудование является "Абстрактной фабрикой", которая создает части корпуса автомобиля. Один и тот же механизм используется для штамповки правых дверей, левых дверей, правых передних крыльев, левых передних крыльев, капота и т.п. у различных моделей машин. С помощью роликов для изменения формы штампа, конкретные классы производятся механизмами, которые могут изменяться за три минуты [16].

 

Паттерны

Рис.1. Пример штамповки "Абстрактной фабрикой".

Строитель

Шаблон "Строитель" отделяет построение сложного объекта от его представления так, что одно и то же построение процесса может создавать различные представления. Этот шаблон применяется ресторанами быстрого питания для комплектования детского меню. Детское питание обычно состоит из главного блюда, гарнира, напитка и игрушки (например, гамбургер, картофель фри, кока-кола и автомобильная игрушка). Заметьте, что в содержание детского меню могут вводиться вариации, но процесс комплектования остается одинаковым. Заказывает ли потребитель гамбургер, чизбургер или курицу — процесс один и тот же. Работник за прилавком указывает команде собрать главное блюдо, гарнир и игрушку. Эти предметы помещаются в пакет. Напиток наливается в чашку и ставится рядом с пакетом. Этот же самый процесс используется и конкурирующими ресторанами.

Паттерны

Рис.2. Диаграмма взаимодействий объектов для "Строителя" на примере комплектования детского меню.

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

"Фабричный метод" задает интерфейс для создания объектов, но оставляет подклассам решать, какие именно классы будут создавать экземпляры. Отливка формовочного пресса демонстрирует такой шаблон. Производители пластмассовых игрушек подвергают обработке пластмассовый формовочный порошок, и заливая пластмассу в пресс, придают ей желаемую форму [15]. Класс игрушки (автомобиль, фигурка и т.п.) определяется прессом.

Паттерны

Рис.3. Объектная диаграмма для "Фабричного метода" на примере отливки формы.

Прототип

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

Паттерны

Рис.4. Объектная диаграмма для "Прототипа" на примере деления клетки.

Одиночка

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

Паттерны

Рис.5. Объектная диаграмма для "Одиночки" на примере Института Президентства.

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

Семь структурных шаблонов были задокументированы "Бандой Четырех". Примеры таких шаблонов могут быть найдены в ручных инструментах, проводке в зданиях, математике, праздновании традиций, торговых каталогах и в банковском деле.

Адаптер

Шаблон "Адаптер" позволяет в случае несовместимых классов работать им вместе, преобразуя интерфейс одного класса в интерфейс, ожидаемый клиентом. Гнездовой ключ представляет собой такой пример "Адаптера". Гнездо присоединенное к храповому механизму, обеспечивает чтобы размер насадки был точно таким же. Типичные размеры гнезд в Соединенных Штатах — 1/2" или 1/4". Очевидно, что 1/2" насадка ключа не подойдет к 1/4" насадке гнезда, если не пользоваться адаптером. 1/2" — 1/4" адаптер имеет 1/2" гнездовой контакт ("мама") для 1/2" насадки ключа, и 1/4" штыревой контакт ("папа") для 1/4" гнезда.

Паттерны

Рис.6. Объектная диаграмма для "Адаптера" на примере гнездового адаптера.

Мост

Шаблон "Мост" отделяет абстракцию от ее реализации так, чтобы они оба могли изменяться независимо. Домашний переключатель, управляющий освещением, потолочным вентилятором и т.п. является примером "Моста". Назначением переключателя является включение или выключение устройства. Действующий переключатель может быть реализован как замыкатель цепи, как простой двухпозиционный переключатель или как переключатель реостатного типа.

Паттерны

Рис.7. Объектная диаграмма для "Моста" на примере электрического переключателя.

Компоновщик

"Компоновщик" сводит объекты в древовидную структуру, и позволяет клиентам обращаться к отдельным объектам и их группам одинаковым образом. "Компоновщиками" являются арифметические выражения, хотя и такой пример является абстрактным. Арифметическое выражение состоит из операнда, оператора (+-*/), и другого операнда. Операнд может быть числом или другим арифметическим выражением. То есть, 2+3 и (2+3)+(4*6), — оба выражения являются правильными.

Паттерны

Рис.8. Объектная диаграмма "Компоновщика" на примере арифметического выражения.

Декоратор

"Декоратор" динамически подключает к объектам дополнительные функции. Хотя картины могут быть повешены на стену как в рамке, так и без, рамками пользуются часто, и как раз за рамку картину вешают на стену. Перед тем как вешать, картина могут быть украшена багетом или установлены в рамку так, чтобы и картина, и багет, и рамка образовали единую визуальную композицию.

Паттерны

Рис.9. Объектная диаграмма для "Декоратора" на примере обрамленной картины.

Фасад

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

Паттерны

Рис.10. Объектная диаграмма для "Фасада" на примере заказа по телефону.

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

"Приспособленец" эффективно использует большое количество объектов совместно. Примером "Приспособленца" является общая коммутируемая телефонная сеть. Имеется несколько устройств, таких как тоновые генераторы звонка, импульсные генераторы и цифровые приемники, которые могут использоваться абонентами совместно. Абонент не знает сколько устройств объединены в пул, когда он поднимает трубку, совершая вызов. Все, что имеет значение для абонента — что тоновый набор работает, сигнал отзыва получен и тогда вызов совершен.

Паттерны

Рис.11. "Приспособленец" на примере тонового генератора звонка.

Заместитель

"Заместитель" вводит заменителя или обладающего полномочиями для обеспечения доступа к объекту. Чек или банковское поручение является заменителем денежных средств на счету. Чек может использоваться вместо наличных денег для совершения покупок и первичного контроля доступа к суммам на текущем счету.

Паттерны

Рис.12. Объектная диаграмма для "Заместителя" на примере банковского поручения.

Шлюз (Gateway)

Создает простой API с необходимыми методами, для общения с внешним источником данных.

Паттерны — примеры из жизни

Типовое решение интерфейс также упрощает работу с интерфейсом API, однако оно создается самим разработчиком внешней службы и предназначено для общего употребления. В свою очередь, шлюз разрабатывается клиентом для использования конкретным приложением. Кроме того, интерфейс доступа, предоставляемый объектом интерфейса, всегда отличается от интерфейса стоящего за ним объекта, в то время как интерфейс шлюза может представлять собой точную копию инкапсулируемого интерфейса (для тестирования или замены источника данных суррогатным объектом).Ряд существенных отличий по отношению к выше перечисленным решениям:

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

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

"Бандой Четырех" были задокументированы одиннадцать поведенческих шаблонов. Примеры таких шаблонов можно найти в сортировке монет в банке, в ресторанных заказах, в музыке, на транспорте, в автомастерской, в торговых автоматах и в жилищном строительстве.

Цепочка обязанностей

Шаблон "Цепочка обязанностей" избегает прямого запроса отправителя к получателю, давая возможность обработать запрос более чем одному объекту. Механическая сортировка монет в банке использует "Цепочку ответственности". В отличие от отдельной щели для монеты каждого достоинства с накопителем, используется единственная щель. Когда монета падает, она автоматически направляется механизмом в соответствующий накопитель внутри банка.

Паттерны

Рис.13. Объектная диаграмма для "Цепочки ответственности" на примере сортировки монет.

Команда

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

Паттерны

Рис.14. Диаграмма взаимодействия объекта "Команды" на примере обедающего.

Интерпретатор

Шаблон "Интерпретатор" задает грамматическое представление для языка и интерпретатора для интерпретирования грамматики. Музыканты являются примерами "Интерпретатора". Высота звука и его продолжительность может быть представлена в музыкальной нотации на нотном стане. Эта нотация представляет собой музыкальный язык [14]. Музыканты, играя музыку с нот, способны воспроизвести оригинальную высоту и продолжительность каждого записанного в нотации звука.

Паттерны

Рис.15. Объектная диаграмма для "Интерпретатора" на музыкальном примере .

Итератор

"Итератор" предоставляет последовательный доступ к элементам составного объекта, не раскрывая нижележащей структуры этого объекта. У телевизоров первого поколения, для переключения каналов использовался циферблат. При переходе к нужному каналу, телезрителю требовалось двигать переключатель через каждую позицию канала, независимо от того, есть ли вещание по текущему каналу или нет. В современных телевизорах используются кнопки "Next" и "Prev". Когда телезритель нажимает кнопку "Next", будет показан следующий канал. Если вы смотрите телевизор в отеле незнакомого города и ищете интересную передачу или фильм, номер канала вас не интересует. Если содержание вас не устраивает — вы будете пользоваться кнопкой "Next", при этом номер канала не так важен.

Паттерны

Рис.16. Объектная диаграмма для "Итератора" на примере переключателя каналов.

Посредник

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

Паттерны

Рис.17. "Посредник" на примере диспетчерской вышки аэропорта.

Хранитель

"Хранитель" делает снимок и облекает в конкретную форму внутреннее состояние объекта, с тем чтобы восстановить это его состояние позднее. Такой шаблон широко распространен в "сделай сам" механике восстановления автомобильных барабанных тормозов. Барабаны снимаются с обеих сторон, открывая вид как левого, так и правого тормозов. Разбирается только одна сторона, а другая используется в качестве "Хранителя" того, как детали тормозов соединены вместе [8]. Только когда работа с одной стороны полностью завершена, разбирается вторая сторона. Когда разбирается вторая сторона, первая служит в качестве "Хранителя".

Паттерны

Рис.18. Объектная диаграмма "Хранителя" на примере ремонта тормозов.

Наблюдатель / Обозреватель

"Наблюдатель" задает отношение "один ко многим" так, чтобы когда один объект меняет свое состояние, другие получают уведомления и автоматически обновляются.

Пример 1: аукцион

Некоторые аукционы представляют собой такой шаблон. Каждый участник торгов имеет карточку с номером, которая используется для указания ставки. Аукционист начинает торги, и "наблюдает" когда карточка будет поднята, подтверждая ставку. Подтверждение ставки изменяет цену предложения, которая передается всем участникам торгов в форме новой ставки.

Паттерны

Рис.19. "Наблюдатель" на примере аукциона.

Пример 2: обычная система доставки почты

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

Важно

Существует две типичные модели для наблюдателя, основанные на способе передачи данных. Это может быть модель или модель "pull". В модели push данные передаются вместе с уведомлением. Примером этого является доставка почты, подписки на журналы и т. д. В модель pull, клиент будет уведомлен о том, что происходит. Но, это всегда ответственность клиента проверить, есть ли соответствующие данные или нет. Примером этого является RSS-каналы. Всякий раз, когда есть изменения на веб-сайте, и если вы подписались на канал, вы получите уведомление. Но, это до вас, чтобы вернуться и посмотреть, если вы заинтересованы.

Состояние

Шаблон "Состояние" позволяет объекту менять свое поведение, когда его внутреннее состояние изменилось . Этот шаблон можно наблюдать в торговом автомате. Торговые автоматы определяют свое состояние основываясь на реестре товаров, количестве полученных денег, возможности вносить изменения и т.д. Когда деньги приняты и выбор сделан, торговый автомат либо выдаст товар и не изменит свое состояние, либо выдаст продукт и изменит свое состояние, либо не выдаст продукт из-за недостаточного количества денег или исчерпания запасов продукта.

Паттерны

Рис.20. Объектная диаграмма для "Состояния" на примере торгового автомата.

Стратегия

"Стратегия" задает набор алгоритмов, которые могут быть использованы как взаимозаменяемые. Вид доставки в аэропорт является примером "Стратегии". Существует несколько вариантов: на собственном автомобиле, вызвать такси, на межаэропортном спецтранспорте, на городском автобусе или лимузине. До некоторых аэропортов также можно добраться и на метро или даже на вертолете. Любой из этих видов доставки путешественников в аэропорт может стать взаимозаменяемым. Пассажир должен выбрать "Стратегию", основываясь на компромиссе между ценой, удобством и временем.

Паттерны

Рис.21. Объектная диаграмма для "Стратегии" на примере доставки в аэропорт.

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

"Шаблонный метод" задает каркас алгоритма в отдельных операциях, и уступает некоторые шаги субклассам. В жилищном строительстве "Шаблонный метод" используется при разработке новых типовых проектов. Типовой проект состоит из ограниченного количества планов помещений, с различными вариациями для каждого плана. Внутри такого плана, фундаменты, окна, сантехника и проводка будут для каждого дома идентичными. Вариации вводятся на последних стадиях разработки, для производства более широкого спектра моделей.

Паттерны

Рис.22. "Шаблонный метод" на примере базового типового проекта.

Посетитель

Шаблон "Посетитель" представляет собой операцию, исполняемую на элементах объектной структуры, без изменения классов, с которыми он работает. Этот шаблон можно обнаружить в работе службы такси. Когда кто-либо звонит в службу такси, он становится частью списка заказчиков службы. Затем служба направляет машину заказчику (принимает посетителя). Садясь в такси, или становясь его Посетителем, заказчик уже не контролирует свое перемещение, это делает (водитель) такси.

Паттерны

Рис.23. Диаграмма взаимодействия объектов для "Посетителя" на примере вызова такси.

Выводы

Не программные примеры каждого шаблона проектирования программного обеспечения, каталогизированные "Бандой Четырех", показаны реально существующими. Можно теперь удивиться практическому смыслу этих примеров. Эти не программные примеры способствуют повышению коммуникативной способности языка шаблонов и полезны как средство обучения шаблонам.

Повышение коммуникативной способности языка шаблонов

Александер надеялся, что правильные шаблоны приведут к появлению общего языка, который будет поддержан всеми [2]. Внутри сообщества проектирования программного обеспечения, шаблоны рассматриваются как путь разработки набора языков для эффективной коммуникации между коллегами [4, 17]. Шаблоны, как ожидается, предоставят общий словарь для обсуждения структур, больших чем модули, процедуры и объекты [10].

Одним из важнейших элементов языка являются ментальные образы, связанные с символами языка. В языке, задаваемая конфигурация символов имеет смысл только тогда, когда можно легко понять ее содержание, которое включает и его ментальное представление [7]. Важность ментальных образов для языка шаблонов не отрицал и Александер. Он утверждал, что язык не является морфологически полным, пока типы построений, которые язык генерирует, не смогут быть визуализированы конкретным образом [1]. В проектировании программного обеспечения, Дирк Риле (Dirk Riehle) и Хайнц Цуллигхофен (Heinz Züllighoven) признают важность конкретных примеров в ознакомлении нашего восприятия с предметной областью [18].

Если шаблоны проектирования программного обеспечения станут всеобщим языком среди программистов, то станут важными и совместно используемые ими смысловые значения. Если проектные решения станут обсуждать, но не понимать, проектировщики будут вынуждены снимать с себя ответственность за завершение работы [19]. Обыденные примеры облегчают понимание, поскольку в ходе понимания чего-либо, люди должны найти в памяти ближайший предмет, с которым оно соотносится [20]. Проекты в AG Communication Systems, там где широко используются шаблоны проектирования, часто сопровождаются не программными примерами для иллюстрации связей в шаблонах. Примеры помогают прийти к общему пониманию между проектировщиками. Установив общее понимание на раннем этапе процесса проектирования, обсуждение между проектировщиками становится намного более эффективным на протяжении всего жизненного цикла проекта.

Не программные примеры как средство обучения шаблонам

Студентам требуются примеры, когда им представляют новые концепции. Это стало очевидным во время испытательного курса по изучению шаблонов проведенного в AG Communication Systems, и то же самое отмечалось другими [12]. Когда изучается что-то новое, студент естественно стремится использовать предыдущие знания в попытках понять новые концепции [6]. По этой причине, при первом знакомстве с шаблонами проектирования программного обеспечения нужно приводить больше примеров [12]. Конкретные примеры должны быть хорошо знакомы студентам, а не экспертам [3]. Приводя знакомые примеры мы не увеличиваем объем материала, который нужно будет изучить еще. В то же время, выбор примера вне компетенции студента, оставляет его за рамками вовлечения в приводимый пример и цель нового материала теряется. Поскольку шаблоны, в конечном счете, должны постоянно находиться в собственной голове [11], используйте те примеры, которые понятны и знакомы как можно большому количеству людей, а учебные материалы могут быть построены на уже закрепившихся в памяти примерах.

Сравнение

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

Порождающие шаблоны проектирования (Creational)

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

Пример из жизни: строительная бригада, которая умеет строить Дом с Садом, или Дом с бассейном, или Дом с гаражом и бассейном

Класс, последовательный вызов функций которого, создают объект только одного вида, но часто с разным содержимым: смотри пример из жизни. Хорошей реализацией считается, когда в классе-строителе есть функция финализации (finalize), вызов которой, помечает данный объект свойством законченности, т.е. объект становится более неизменяемым.

Прототип

Пример из жизни: процесс деления клеток

Пример в программировании: функция, которая умеет создавать копию объекта в котором она находится или копию переданного в нее объекта

Структурные шаблоны проектирования (Structural)

Паттерны — примеры из жизни

Декоратор

Также известен как: Обёртка, Decorator

Пример из жизни

Декоратор - человек, который принимает заказы только на оформление чего-либо, например: театр, магазин, картина.

В программном смысле

Класс, расширяющий функциональность другого класса c использованием наследования.

Паттерны — примеры из жизни

Фасад

Также известен как: Facade

Пример из жизни

Завод по изготовлению какой-либо продукции имеет офис, в котором находится персонал принимающий заявки от клиентов и отдающий распоряжения на изготовление продукции.

В программном смысле

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

Важный момент

Часто целью данного паттерна является соблюдение закона Деметры.

Фабрика vs Фасад

Фасад не создает новые объекты.

Паттерны — примеры из жизни

Шлюз

Также известен как: Gateway

Пример из жизни

Любой компьютер при подключении к интернету, должен себя идентифицировать у интернет-провайдера, обычно, компьютер показывает Вам форму ввода логина/пароля (форма в этом случае является реализацией паттерна Фасад), которые после ввода отправляется на шлюз интернет-провайдера.     

Фасад vs Шлюз,

Фасад реализуется стороной которая обращается куда-либо, а Шлюз реализуется стороной к которой обращаются.

Паттерны — примеры из жизни

Компоновщик

Также известен как: Дерево, Composite

Пример из жизни

Компоновщик (от лат. componere «складывать») - человек, который может сложить предметы в коробку, и предоставить информацию о том, сколько в коробке предметов, какова их общая стоимость, и т.п. обобщенную информацию. Так же, компановщики часто собирают что-то большое из чего-то маленького, например автомобиль из деталей, деталь автомобиля из более мелких деталей.

В программном смысле

Функция, которая создает основной объект и наполняет его второстепенными объектами, при этом основной и второстепенные объекты должны быть одного типа (имплементируя единый интерфейс).

Паттерны — примеры из жизни

Адаптер

Также известен как: Adapter / Wrapper

Пример из жизни

Переходник с одного типа розетки на другой тип розетки, и есть Адаптер.

В программном смысле

Объект реализующий интерфейсы двух других объектов, которым нужно взаимодействие друг с другом.

Паттерны — примеры из жизни

Мост

Также известен как: Bridge

Пример из жизни

Есть 2 города разделяемые рекой, для взаимодействия между ними строят мост, города развиваются каждый по-своему, но мост не меняется, городам приходится учитывать строение моста (города подстраиваются под мост, а не мост под города).

В программном смысле

Чаще всего, мост - это класс с интерфейсом, который должны реализовать оба объекта (которым нужно взаимодействие между собой)

Адаптер vs Мост

Паттерн Мост очень похож на Адаптер, но Адаптер адаптируется под обе стороны, а Мост говорит, чтобы обе стороны подстраивались под него
Паттерны — примеры из жизни

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

Альтернативные названия: Flyweight

Пример из жизни

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

В программном смысле

Класс реализующий существующий интерфейс, для взаимодействия.

Важный момент

В современном мире, очень часто данный паттерн связывают с разделяемой памятью, но исторически было не так однозначно.

Адаптер vs Приспособленец

Приспособленец это конечная вещь, а Адаптер, это промежуточная вещь
Паттерны — примеры из жизни

Заместитель

Также известен как: Proxy

Пример из жизни

Заместитель руководителя имеет те же полномочия что и руководитель (в момент отсутсвия руководителя).

В программном смысле

Объект, который перехватывает вызовы к оригинальному объекту.

Поведенческие шаблоны проектирования (Behavioral)

Паттерны — примеры из жизни

Цепочка обязанностей

Также известен как: CoR, Chain of Command, Chain of Responsibility

Пример из жизни

Вы купили новый компьютер, но он не включается - Вы звоните в компанию-производитель, и начинается цепочка получения ответа:

  1. с Вами говорит робот, и если он не смог дать ответ, то переключает Ваш звонок далее
  2. с Вами говорит оператора поддержки клиентов, и если он не смог дать ответ, то переключает Ваш звонок далее
  3. с Вами говорит инженер и т.д.

В программном смысле

Цепочка образуется из звеньев цепи - объектов, и имеет следующие особенности:

  1. каждое из звеньев цепи имеет ссылку на следующее звено в цепи (одно звено знает только про одно звено, кроме последнего звена, которое не знает ничего о другом звене), таким образом, при получении запроса звено может что-то сделать с запросом, и обязано передать запрос следующему звену в цепочке.
  2. если звену не интересен запрос, звено не обрабатывает запрос и просто передает его следующему звену
  3. длина цепочки не имеет никакого значения
  4. передавая запрос в первое звено, Вы можете быть уверены, что все звенья в цепи смогут его обработать
  5. есть и подход, когда звено не обязательно должно передавать запрос дальше
Паттерны — примеры из жизни

Команда

Также известен как: Command

Пример из жизни

Генерал отдает Полковнику команду "наступление на противника", каждый из Полковников отдает свою команду, например "наступление по левому флангу". Следовательно, Генералу важно, чтобы каждый Полковник правильно понял команду, Полковнику важно, чтобы каждый Рядовой правильно понял команду. Чтобы все правильно понимали команду, нужно всех обучить всем известным командам.

Важно: паттерн подразумевает простую возможность достижения чего-то более сложного

В программном смысле

Объект X реализованный по интерфейсу Command, о котором знает объект A, чтобы объект A мог обращаться к объекту X по заранее согласованным функциям интерфейса.

Фасад vs Команда

Паттерн "Фасад" не обязывает реализовывать какой-либо интерфейс, а паттерн "Команда" - обязывает (Генерал знает команду, благодаря которой Полковник сделает все правильно).

Паттерны — примеры из жизни

Итератор

Также известен как: Iterator

Пример из жизни

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

В программном смысле

Идея паттерна Итератор состоит в том, чтобы вынести поведение обхода коллекции из самой коллекции в отдельный класс. Отсюда, имеет 2 вида итераторов:

  1. Итератор-класс имеющий реализацию, подстраиваясь под который можно получить функции итерации в своем классе.
  2. Итератор-класс, позволяющий получить последовательный доступ к элементам класс-агрегата, при этом класс-агрегат не будет ничего реализовывать и знать о том, что его итерируют.
Паттерны — примеры из жизни

Стратегия

Также известен как: Strategy

Пример из жизни

Вам нужно добраться до аэропорта. Можно доехать на автобусе, такси или велосипеде. Здесь вид транспорта является стратегией. Вы выбираете конкретную стратегию в зависимости от контекста — наличия денег или времени до отлёта.

В программном смысле

Класс Context имеет функцию поиска, которая пробегается по известным ей классам (эти классы обязаны имплементировать интерфейс Strategy требующей создать функцию, которую будет вызывать класс Context).

Паттерны — примеры из жизни

Посредник

Также известен как: Intermediary, Controller, Mediator

Пример из жизни

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

В программном смысле

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

Посредник vs Фасада

Фасад оговаривает вопрос структуры (кто кому подчиняется) а Посредник реализует эту структуру.

Паттерны — примеры из жизни

Хранитель

Также известен как: Memento, Снимок

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

Терминология

Паттер считается реализованным, если в функционале появляется возможность восстанавливать состояние некого объекта (назовем его Originator), и достигнуто это с помощью трех классов:

  1. «Originator/Создатель» - объект/значение
  2. «Caretaker/Опекун» - объект, в который помещается Originator
  3. «Memento/Хранитель» - объект обертка Originator-а (рудемент, которого не должно быть в той интерпретации паттерна, которую я наблюдаю в настоящий момент в многих интернет-источниках)

Простой пример

OriginatorObject = new Originator('{"value":"1"}') // создаем объект из переданного json

Caretake.set(OriginatorObject) // функция set преобразует OriginatorObject в json и сохранит его в себе 

OriginatorObject.value = 2 // изменяем состояние объекта OriginatorObject 

OriginatorObject = Caretake.get() // восстановление OriginatorObject с помощью вызова new Originator('{"value":"1"}')

Внимание, в примере нет объекта «Memento/Хранитель», потому что «Memento/Хранитель» это внутренний класс, который используется объектом Caretake, чтобы сохранить состояние объекта/значения Originator. Практически, вместо «Memento/Хранитель» может быть простая сериализация значения в json / из json.

 

Наблюдатель

Также известен как: Издатель-Подписчик, Слушатель, Observer

Для реализации паттерна Вам понадобится:

  • Event (Событие) - событие, которое может возникнуть (например пришло письмо)
  • Subject (Издатель) - объект, который уведомляет о событии
  • Observer (Подписчик/Слушатель) - объект, который подписывается на событие и ожидает уведомление

Подписчик vs Слушатель

  • Подписчик (Subscriber) - объект, который подписался сразу на несколько событий одного объекта (например человек подписался на два журнала одного издательства)
  • Слушатель (Listener) - объект, который подписался только на одно событий одного объекта (например человек подписался на один журнала одного издательства)

Виды уведомлений

  • push - когда Observer-у предоставляется вся информация о уведомлении (почтальон вручил ценную посылку прямо в руки человека)
  • pull - когда Observer подтягивает информация о уведомлении (человек получил уведомление о том, что ему пришла посылка, теперь он должен сходить на почту за посылкой)

Пример из жизни

Почтовое отделение и человек.

Нюанс

Иногда, Event (Событие) и Subject (Издатель) объединяют, пример из жизни: знаменитость может уведомить лично своих фанатов.

Celebrity-Fan Example

В программном смысле

Observer {
    abstract public update ( SplSubject subject ) : void // этот метод будет вызван, когда в объекте Subject произойдет изменение состояния
}
Subject {
    abstract public attach ( SplObserver observer ) : void
    abstract public detach ( SplObserver observer ) : void
    abstract public notify ( void ) : void // объект Subject при изменении своего состояния, должен вызывать метод update(this) каждого Observer-а
}

 

Заключение

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

Источник: 1 - 2 - 3 - 4 - 5 - 6 - 7

Оцени публикацию:
  • 0,0
Оценили человек: 0

Похожие статьи:

Справочники и учебники:


Предложения и пожелания:
Ваше имя:
Ваш E-mail:
Сколько будет Οдин + Τри
Главная
X

youtube.com/watch?v=7hFivbgIEqk

При полном или частичном использовании материалов данного сайта, ссылка на сайт "yapro.ru" обязательна как на источник информации.
Автоматический импорт материалов и информации с сайта запрещен.
Copyrights © 2007 - 2019 YaPro.Ru

Главная » Веб-мастеру » PHP »