Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
теория ООП .doc
Скачиваний:
10
Добавлен:
26.09.2019
Размер:
199.17 Кб
Скачать

Структурные паттерны

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

Адаптер (Adapter) преобразует интерфейс класса в некоторый другой интефейс ожидаемый клиентами. Обеспечивает совместную работу классов, которая была бы невозможна без данного паттерна из-за несовместимости интерфейсов.

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

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

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

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

Заместитель (Proxy) замещает другой объект для обеспечения контроля доступа к нему. Используются следующие разновидности заместителей:

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

  • виртуальный заместитель создает «тяжелые» объекты по требованию (например, когда вместо изображения появляется рамка);

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

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

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

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

Мост (Bridge) отделяет абстракцию от реализации, благодаря чему появляется возможность независимо изменять и то и другое. Такое разделение облегчает разбиение системы на слои и тем самым позволяет улучшить ее структуру.

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

Паттеpн дает возможность конфигурировать реализацию абстракции во время выполнения, а также изменять класс реализации без перекомпиляции класса абстракции и его клиентов.

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

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

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

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

Фасад (Facade) предоставляет унифицированный интерфейс к множеству интерфейсов в некоторой подсистеме. Определяет интерфейс более высокого уровня, облегчающий работу с подсистемой.

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

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

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