Перейти к основному содержимому

Что это такое

Паттерн Компоновщик (Composite) работает с отдельными вещами и с группами вещей через один и тот же интерфейс. У файла есть размер; у папки, полной файлов (и папок), размер тоже есть — поэтому оба реализуют size(), и код, который складывает размеры, никогда не спрашивает, что именно у него в руках.

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


Пример: файлы и папки

В интерфейсе Item один метод. Файл отвечает своим собственным размером; папка спрашивает всё, что внутри, и складывает — рекурсия получается сама собой.

Один интерфейс для листа и для группы

$root->size() обходит всё дерево без единой проверки типа: папке всё равно, является ли элемент файлом на 4 КБ или другой папкой, в которой спрятано ещё десять.

Prompt
Напишите PHP-скрипт с паттерном Composite: интерфейс Item с методом size, лист File с фиксированным размером и Folder, который содержит объекты Item и рекурсивно суммирует их размеры. Постройте небольшое дерево (корневая папка с файлом и папкой docs, в которой лежат два файла) и выведите размер docs и размер root.
Вывод: PHP-скрипт
One interface for leaf and group

Когда его применять

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

Не применяйте для плоских списков. Массиву с циклом никакой паттерн не нужен.


Плюсы и минусы

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

Минусы: общий интерфейс может навязывать листьям неуместные методы (что такое «добавить потомка» для файла?); слишком общие компоновщики трудно ограничить.