Компоновщик
Composite
Назначение
Компоновщик (Composite) - структурный паттерн проектирования, который позволяет сгруппировать объекты в древовидные структуры для представления иерархий "часть-целое". Позволяет клиентам единообразно трактовать индивидуальные и составные объекты.
Используется в случаях, когда:
Необходимо объединять группы схожих объектов и управлять ими.
Объекты могут быть как примитивными (элементарными), так и составными (сложными). Составной объект может включать в себя коллекции других объектов, образуя сложные древовидные структуры.
Пример: директория файловой системы состоит из элементов, каждый их которых также может быть директорией.
Код клиента работает с примитивными и составными объектами единообразно.
Решаемые задачи
композиция объектов
Дает возможность представления иерархии объектов вида часть-целое. С помощью композиции можно создавать древовидные структуры объектов, группировать объекты в контейнеры и управлять ими единообразно.
предоставление единообразного интерфейса
Единообразная трактовка клиентами составных и индивидуальных объектов, то есть паттерн компоновщик позволяет клиентам взаимодействовать с отдельными объектами и группами объектов (составными объектами) через единый интерфейс.
В качестве клиентов может выступать пользовательский код или другие классы, взаимодействующие с объектами иерархии Composite.
создание рекурсивных операций
Паттерн компоновщик позволяет выполнять операции на составных объектах рекурсивно. Когда операция вызывается на составном объекте, он автоматически распространяет операцию на все объекты в иерархии, включая объекты, содержащие другие объекты. Происходит рекурсивный проход по иерархии. Таким образом, можно легко применять операции как к отдельным объектам, так и ко всему дереву объектов.
UML диаграмма
Преимущества
упрощение архитектуры клиентского кода
Предоставление клиентскому коду удобного и единого интерфейса для работы как с отдельными, так и с составными объектами позволяет ему работать с иерархией объектов без необходимости проверять их типы и выбирать разные пути обработки.
повышение гибкости и расширяемости системы за счет добавления новых компонентов в иерархию без изменения существующего кода
возможность выполнения рекурсивных операций на составных объектах
предоставление удобных методов для добавления, удаления и обхода компонентов в иерархии объектов
Недостатки
потребность в создании сущности, отвечающей за за логику сборки компоновщика, которая может оказаться нетривиальной
нетривиальная логика обхода и работы с сущностью как с контейнером, если в компоновщике содержатся другие компоновщики
потеря типизации
Использование общего интерфейса может привести к потере типизации и нарушению статической проверки типов. Появляется необходимость решать проблему типизации вынесением всех методов из компоновщика в класс компонента. В свою очередь, это приводит к следующей проблеме
появление нелогичных операций
Максимизация интерфейса класса компонент, приводит к тому, что у подклассов появляются нелогичные операции
Связь с другими паттернами
Цепочка обязанностей: отношение компонент-родитель используется в паттерне цепочка обязанностей.
Декоратор: паттерн декоратор часто применяется совместно с компоновщиком. Когда декораторы и компоновщики используются вместе, у них обычно бывает общий родительский класс. Поэтому декораторам придется поддержать интерфейс компонента такими операциями, как Add, Remove.
Приспособленец: паттерн приспособленец позволяет разделять компоненты, но ссылаться на своих родителей они уже не могут.
Итератор: итератор можно использовать для обхода составных объектов.
Посетитель: посетитель локализует операции и поведение, которые в противном случае пришлось бы распределять между классами Composite и Leaf
Leaf – лист:
– представляет листовые узлы композиции и не имеет потомков;
– определяет поведение примитивных объектов в композиции;
Composite – составной объект:
– определяет поведение компонентов, у которых есть потомки;
– хранит компоненты-потомки;
– реализует относящиеся к управлению потомками операции в интерфейсе класса Component;
Component – компонент:
– объявляет интерфейс для компонуемых объектов;
– предоставляет подходящую реализацию операций по умолчанию, общую для всех классов;
– объявляет интерфейс для доступа к потомкам и управления ими;
Last updated
Was this helpful?