НОУ ИНТУИТ | Лекция | Структурные шаблоны проектирования

Аннотация: Данная глава нашей книги содержит описание наиболее «низкоуровневых» паттернов, описывающих структурные особенности создаваемых программных продуктов. Шаблоны структурного типа практически не содержат абстрактных описаний сложных компонентов. Они состоят из однозначных, понятных и простых элементов, которые являются наиболее оптимальным способом решения задачи разработки комплексных, высококачественных систем, как для разработчиков и группы поддержки, так и для конечных пользователей. Структурные паттерны являются одним из базисных элементов сферы шаблонов проектирования. С их применением создаются более сложные, уже рассмотренные нами архитектурные и интеграционные паттерны. Книга организована постепенным снижением с уровня более абстрактных понятий к специализированным. Это позволит читателю взглянуть на картину в целом и выделить для себя наиболее значимые аспекты в дальнейшем развитии и обучении. Именно поэтому данная глава является связующим звеном при переходе между уровнями абстракции.

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

Введение

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

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

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

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

Шаблоны структуры объектов

В качестве структурных паттернов проектирования сегодня мы рассмотрим следующие:

«Адаптер», «Декоратор», «Заместитель», «Информационный эксперт», «Компоновщик», «Мост», «Низкая связанность», «Приспособленец», «Устойчивый к изменениям», «Фасад».

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

Адаптер

Структурный шаблон «Адаптер» востребован в ситуации, когда необходимо организовать использование функций определенного бизнес-объекта, недоступного для модификации. Это происходит, когда система или ее компонент имеют требуемые данные и функциональность, но не имеют подходящего интерфейса.

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

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

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

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

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

intuit.ru/2010/edi»> «Банда четырех» (основная группа евангелисты объектно-ориентированного подхода к разработке программного обеспечения) следующим образом определяет назначение паттерна»Адаптер»:

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

Шаблон «Адаптер» позволяет включать уже существующие объекты в новые структуры, независимо от различий в их интерфейсах. Интерфейс включающего объекта и его класс приводится в соответствие с новыми требованиями, а вызовы методов преобразуются в вызовы методов включенного класса.

Применение шаблона «Адаптер» во время разработки программного продукта позволяет не принимать во внимание возможные различия в интерфейсах уже существующих объектов. Если имеется класс, обладающий требуемыми методами и свойствами, то при необходимости всегда можно будет воспользоваться рассматриваемым шаблоном для приведения его интерфейсов к нужному виду.

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

На сегодняшний момент распространены два типа этого шаблона:

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

Выбор варианта определяется спецификой проблемной области.

Шаблон «Адаптер» можно сравнить с электрическим переходником, необходимым для подключения «евро» -вилок с цилиндрическими наконечниками к азиатским розеткам.

Рис. 5.2. 1. Шаблон «Адаптер»

Декоратор

Если требуется возложить дополнительные обязанности на отдельный объект, а не на класс, генерирующий объекты, целесообразно применять шаблон «Декоратор».

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

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

  • Системный компонент определяет интерфейс объекта, на который могут быть динамически возложены дополнительные обязанности.
  • Конкретный компонент определяет объект, на который возлагаются дополнительные обязанности.
  • Шаблон «Декоратор» хранит ссылку на объект (компонент), определяет его интерфейс и переадресует на него рабочие запросы.

«Декоратор» позволяет реализовать большую гибкость, чем у статического наследования, создаваемого путем разработки подклассов.

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

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

Заместитель

В случаях, когда необходимо управлять доступом к объекту, так чтобы создавать громоздкие компоненты только «по требованию», оптимально использовать шаблон «Заместитель».

Суть «Заместителя» состоит в том, что он хранит ссылку, которая позволяет ему обратиться к реальному субъекту только при необходимости, задействуя системные ресурсы.

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

Шаблон «Заместитель» может иметь и другие обязанности:

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

Шаблон «Заместитель» достаточно часто используют в паре с шаблоном «Адаптер».

Информационный эксперт

Когда в системе должна аккумулироваться, преобразовываться и удаляться необходимая информация, применяется шаблон «Информационный эксперт».

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

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

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

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

21 июня 2021

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

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

Структурные паттерны проектирования

Эти паттерны отвечают за построение удобных в поддержке иерархий классов:

  • Адаптер
  • Мост
  • Фасад
  • Декоратор

Адаптер. Суть паттерна

Позволяет объектам с несовместимыми интерфейсами работать вместе.

Адаптер. Проблема.

Адаптер. Решение.

Адаптер. Структура.

Клиент – класс, который содержит существующую бизнес-логику программы.
Адаптер – класс, который может одновременно работать и с клиентом, и с сервисом. Он реализует клиентский интерфейс и содержит ссылку на объект сервиса.
Клиентский интерфейс – описывает протокол, через который клиент может работать с другими классами.
Сервис – класс, обычно сторонний. Клиент не может использовать этот класс напрямую, так как сервис имеет непонятный ему интерфейс.

Адаптер. Применимость.

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

Адаптер. Преимущества и недостатки.

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

Мост

Разделяет один или несколько классов на две отдельные иерархии — абстракцию и реализацию, позволяя изменять их независимо друг от друга.

Мост. Проблема.

Мост. Решение.

Мост. Структура.

      Абстракция – содержит управляющую логику. Код абстракции делегирует реальную работу связанному объекту реализации.
      Расширенные абстракции – содержат различные вариации управляющей логики.
      Клиент – работает только с объектами абстракции.
      Реализация – задаёт общий интерфейс для всех реализаций. Все методы, которые здесь описаны, будут доступны из класса абстракции и его подклассов.
      Конкретные реализации – содержат платформо-зависимый код.

      Мост. Применимость.

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

      Мост. Преимущества и недостатки.

      Преимущества:

      • Позволяет строить платформо-независимые программы.
      • Скрывает лишние или опасные детали реализации от клиентского кода.
      • Реализует принцип открытости/закрытости.

      Недостатки:

      • Усложняет код программы из-за введения дополнительных классов.

      Фасад.

      Предоставляет простой интерфейс к сложной системе классов, библиотеке или фреймворку.

      Фасад. Проблема.

      Фасад. Решение.

      Фасад. Структура.

      Клиент – использует фасад вместо прямой работы с объектами сложной подсистемы.
      Фасад – предоставляет быстрый доступ к определённой функциональности подсистемы. Он «знает», каким классам нужно переадресовать запрос, и какие данные для этого нужны.
      Сложная подсистема – состоит из множества разнообразных классов. Для того, чтобы заставить их что-то делать, нужно знать подробности устройства подсистемы, порядок инициализации объектов и так далее.
      Дополнительный фасад – можно ввести, чтобы не «захламлять» единственный фасад разнородной функциональностью. Он может использоваться как клиентом, так и другими фасадами.

      Фасад. Применимость.

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

      Фасад. Преимущества и недостатки.

      Преимущество: изолирует клиентов от компонентов сложной подсистемы.
      Недостаток: фасад рискует стать божественным объектом, привязанным ко всем классам программы.

      Декоратор.
      Позволяет динамически добавлять объектам новую функциональность, оборачивая их в полезные «обёртки».

      Декоратор. Проблема.

      Декоратор. Решение.

      Декоратор. Структура.

      Компонент – задаёт общий интерфейс обёрток и оборачиваемых объектов.
      Конкретный компонент – определяет класс оборачиваемых объектов. Он содержит какое-то базовое поведение, которое потом изменяют декораторы.
      Клиент – может оборачивать простые компоненты и декораторы в другие декораторы, работая со всеми объектами через общий интерфейс компонентов.
      Базовый декоратор – хранит ссылку на вложенный объект-компонент.
      Конкретные декораторы – различные вариации декораторов, которые содержат добавочное поведение.

      Декоратор. Преимущества и недостатки.

      Преимущества:

      • Большая гибкость, чем у наследия.
      • Позволяет добавлять обязанности на лету.
      • Можно добавлять несколько новых обязанностей сразу.
      • Позволяет иметь несколько мелких объектов вместо одного объекта на все случаи жизни.

      Недостатки:

      • Трудно конфигурировать многократно обёрнутые объекты.
      • Обилие крошечных классов.

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

      Позволяет подставлять вместо реальных объектов специальные объекты-заменители.

            Заместитель. Проблема.

                  Заместитель. Решение.

                        Заместитель. Структура.

                        Клиент – работает с объектами через интерфейс сервиса. Благодаря этому, ему можно «подсунуть» объект заместителя.
                        Заместитель – хранит ссылку на объект сервиса. После того как заместитель заканчивает свою работу, он передаёт вызовы вложенному сервису. Заместитель может сам отвечать за создание и удаление объекта сервиса.
                        Интерфейс – сервиса определяет общий интерфейс для сервиса и заместителя. Благодаря этому, объект заместителя можно использовать там, где ожидается объект сервиса.
                        Сервис – содержит полезную бизнес-логику.

                              Заместитель. Применимость.

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

                                    Заместитель. Преимущества и недостатки.

                                    Преимущества:

                                    • Позволяет контролировать сервисный объект незаметно для клиента.
                                    • Может работать, даже если сервисный объект ещё не создан.
                                    • Может контролировать жизненный цикл служебного объекта.

                                    Недостатки:

                                    • Усложняет код программы из-за введения дополнительных классов.
                                    • Увеличивает время отклика от сервиса.

                                          ⟵ Назад

                                          Смотрите также

                                          Архитектор, кто ты?

                                          Запуск тестов внутри контейнеров

                                          Марафон по нагрузочному тестированию: схема общих понятий

                                          Zabbix 5: сущность и принципы применения

                                          Тестирование приложений банковского и финансового секторов: примеры тестовых случаев

                                          Меняем мир сотового ритейла вместе с «Территория возможностей»

                                          Что такое структурный образец? (Определение)

                                          Урок 2 Что такое структурный паттерн?
                                          Цель Определение структурных моделей.

                                          Шаблон структурного проектирования служит планом того, как различные классы и объекты объединяются для формирования более крупных структур. В отличие от созидательных паттернов , которые в основном представляют собой разные способы достижения одной и той же фундаментальной цели, каждый структурный паттерн имеет свою цель.
                                          Вопрос: Что объединяет структурные модели?
                                          Ответ: Все они включают связи между объектами.
                                          В некотором смысле структурные шаблоны подобны более простой концепции структур данных.
                                          Однако шаблоны структурного проектирования также определяют методы, которые соединяют объекты, а не просто ссылки между ними. Кроме того, структуры данных являются довольно статичными сущностями. Они лишь описывают, как данные расположены в структуре. А 9Шаблон структурного проектирования 0017 также описывает, как данные перемещаются по шаблону.
                                          Шаблоны структурных классов используют наследование для объединения интерфейсов или реализаций нескольких классов. Структурные классовые паттерны относительно редки.
                                          Шаблоны структурных объектов используют композицию объектов для объединения реализаций нескольких объектов. Они могут объединять интерфейсы всех составных объектов в один унифицированный интерфейс или предоставлять совершенно новый интерфейс.

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


                                          Структурные шаблоны описывают, как классы и объекты могут быть объединены в более крупные структуры. Разница между шаблонами классов и шаблонами объектов заключается в том, что шаблоны классов описывают, как можно использовать наследование для предоставления более полезных программных интерфейсов.
                                          Шаблоны объектов описывают, как объекты могут быть составлены в более крупные структуры с использованием композиции объектов или включения объектов в другие объекты.
                                          Например, мы увидим, что Шаблон адаптера можно использовать для согласования одного интерфейса класса с другим, чтобы упростить программирование. Мы также рассмотрим ряд других структурных шаблонов, в которых мы комбинируем объекты для обеспечения новой функциональности. Композит именно такой:
                                          «Композиция объектов, каждый из которых может быть либо простым, либо составным объектом».
                                          Шаблон Proxy часто представляет собой простой объект, который принимает место более сложного объекта, который может быть вызван позже, например, когда программа запускается в сетевой среде. Модель наилегчайшего веса — это шаблон для совместного использования объектов, где каждый экземпляр не содержит собственного состояния, а хранит его извне. Это позволяет эффективно совместно использовать объекты для экономии места, когда существует много экземпляров, но только несколько разных типов.
                                          Шаблон Фасад используется для того, чтобы один класс представлял весь подсистема, а шаблон Bridge отделяет интерфейс объекта от его реализации, поэтому вы можете изменять их по отдельности. Наконец, шаблон Decorator можно использовать для динамического добавления обязанностей к объектам.


                                          Структурные модели — обзор. Это часть большой темы, которая… | Даниэль Янковски | Netcompany

                                          Photo by Clint Patterson on Unsplash

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

                                          Главную обзорную страницу можно найти здесь.

                                          Структурные шаблоны описывают метод проектирования, определяя простой способ реализации отношений классов. Они помогают комбинировать объекты для большей структуры.

                                          Существует несколько типов:

                                          • Адаптер/оболочка
                                          • Мост
                                          • Фасад
                                          • Прокси

                                          Если у вас есть два или более несовместимых объекта, вы можете использовать «Оболочку» (я предпочитаю это описание, а не адаптер) чтобы они взаимодействовали друг с другом.

                                          Адаптер/оболочка

                                          На приведенной выше схеме вы можете видеть два интерфейса: « ICar» и « IElectricCar» и два объекта « Car» и « ElectricCar» . «Автомобиль» имеет метод « Заправка ()», который отвечает за заправку бака топливом. Производитель хочет произвести новый тип автомобиля, который нуждается в новых функциях. Он не использует бензин, вместо этого он использует электричество. Производитель также хочет использовать этот новый метод с существующей линейкой автомобилей. Единственное, что для этого нужно сделать, — расширить Refuel()’ метод в классе Car, чтобы понять новый тип и вызвать метод ‘ Charge()’ из интерфейса ‘ IElectricCar ’».

                                          Пример кода:

                                          Другой способ реализации:

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

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

                                          Шаблон проектирования моста

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

                                          Шаблон проектирования моста

                                          В приведенном ниже коде представлена ​​вся функциональность шаблона проектирования моста:

                                          Вот пример клиента:

                                          Здесь мы видим другую реализацию интерфейса, но на этот раз описывающую шаблон моста.

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

                                          Фасад

                                          Пример кода ниже:

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

                                          Прокси

                                          Объект « MSSQLProvider» следует создавать только при необходимости. Он управляется отдельным классом « DataBaseProxy» .