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

Что это такое

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

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


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

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

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

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

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

Когда использовать

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

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


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

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

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