Компонувальник, Composite — структурний шаблон який об'єднує об'єкти в ієрархічну деревоподібну структуру, і дозволяє уніфіковане звертання для кожного елемента дерева.
Призначення
Дозволяє користувачам будувати складні структури з простіших компонентів. Проєктувальник може згрупувати дрібні компоненти для формування більших, які, в свою чергу, можуть стати основою для створення ще більших.
Структура
Ключем до паттерну компонувальник є абстрактний клас, який є одночасно і примітивом, і контейнером(Component). У ньому оголошені методи, специфічні для кожного виду об'єкта (такі як Operation) і загальні для всіх складових об'єктів, наприклад операції для доступу і управління нащадками. Підкласи Leaf визначає примітивні об'єкти, які не є контейнерами. У них операція Operation реалізована відповідно до їх специфічних потреб. Оскільки у примітивних об'єктів немає нащадків, то жоден з цих підкласів не реалізує операції, пов'язані з управління нащадками (Add, Remove, GetChild). Клас Composite складається з інших примітивніших об'єктів Component. Реалізована в ньому операція Operation викликає однойменну функцію відтворення для кожного нащадка, а операції для роботи з нащадками вже не порожні. Оскільки інтерфейс класу Composite відповідає інтерфейсу Component, то до складу об'єкта Composite можуть входити і інші такі ж об'єкти.
Учасники
- Component (Component)
Оголошує інтерфейс для компонованих об'єктів; Надає відповідну реалізацію операцій за замовчуванням, загальну для всіх класів; Оголошує єдиний інтерфейс для доступу до нащадків та управління ними; Визначає інтерфейс для доступу до батька компонента в рекурсивної структурі і при необхідності реалізує його (можливість необов'язкова);
- Leaf (Leaf_1, Leaf_2) — лист.
Об'єкт того ж типу що і Composite, але без реалізації контейнерних функцій; Представляє листові вузли композиції і не має нащадків; Визначає поведінку примітивних об'єктів в композиції; Входить до складу контейнерних об'єктів;
- Composite (Composite) — складений об'єкт.
Визначає поведінку контейнерних об'єктів, у яких є нащадки; Зберігає ієрархію компонентів-нащадків; Реалізує пов'язані з управління нащадками (контейнерні) операції в інтерфейсі класу Component;
Переваги
- Клієнти використовують інтерфейс класу компонентів для взаємодії з об'єктами у складній структурі.
- Якщо виклик здійснюється в листок, запит обробляється безпосередньо.
- Якщо виклик до Composite, він пересилає запит до своїх дочірніх компонентів.
Вади
- Як тільки деревоподібна структура визначена, композитний дизайн робить дерево надто загальним.
- У конкретних випадках важко обмежити компоненти дерева лише окремими типами.
- Для забезпечення обмеження програма повинна спиратися на перевірки виконання часу, оскільки вона не може використовувати систему типу мови програмування.
Приклад реалізації
C++
#include <iostream> #include <deque> using namespace std; // Інтерфейс компонентів struct IQuackable { virtual ~IQuackable() {} virtual void print() const = 0; }; // Конкретні компоненти struct Duck :public IQuackable { virtual void print() const { cout << "Duck " << '\n'; } }; struct MallardDuck :public Duck { virtual void print() const { cout << "Mallard Duck" << '\n'; } }; struct RedheadDuck :public Duck { virtual void print() const { cout << "Redhead Duck" << '\n'; } }; // Компонувальник // Також може бути компонентом class Flock : public IQuackable { protected: deque<IQuackable*> quackers;// контейнер компонентів public: virtual void print() const { for (size_t i = 0; i < quackers.size(); ++i) { quackers[i]->print();// псевдо-рекурсивний виклик } } void add(IQuackable* quacker) { quackers.push_back(quacker); } void remove(size_t i) { if (i < quackers.size()) { quackers.erase(quackers.begin() + i); } } }; void main() { Flock Gang; IQuackable* gang[3] = { new MallardDuck(), new RedheadDuck(), new MallardDuck() }; // додаємо компонувальнику компонентів for (int i = 0; i < 3; ++i) { Gang.add(gang[i]); } Flock* Ducks = new Flock; for (int i = 0; i < 3; ++i) { Ducks->add(new Duck()); } Gang.add(Ducks); // додаємо компонувальника, як компонент іншого компонувальника Gang.print(); }
C#
// Composite pattern -- Structural example using System; using System.Collections.Generic; namespace DoFactory.GangOfFour.Composite.Structural { /// <summary> /// MainApp startup class for Structural /// Composite Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main() { // Create a tree structure Composite root = new Composite("root"); root.Add(new Leaf("Leaf A")); root.Add(new Leaf("Leaf B")); Composite comp = new Composite("Composite X"); comp.Add(new Leaf("Leaf XA")); comp.Add(new Leaf("Leaf XB")); root.Add(comp); root.Add(new Leaf("Leaf C")); // Add and remove a leaf Leaf leaf = new Leaf("Leaf D"); root.Add(leaf); root.Remove(leaf); // Recursively display tree root.Display(1); // Wait for user Console.ReadKey(); } } /// <summary> /// The 'Component' abstract class /// </summary> abstract class Component { protected string name; // Constructor public Component(string name) { this.name = name; } public abstract void Display(int depth); } /// <summary> /// The 'Composite' class /// </summary> class Composite : Component { private List<Component> _children = new List<Component>(); // Constructor public Composite(string name) : base(name) { } public void Add(Component component) { _children.Add(component); } public void Remove(Component component) { _children.Remove(component); } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + name); // Recursively display child nodes foreach (Component component in _children) { component.Display(depth + 2); } } } /// <summary> /// The 'Leaf' class /// </summary> class Leaf : Component { // Constructor public Leaf(string name) : base(name) { } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + name); } } }
Джерела
- http://www.dofactory.com/ [ 29 Квітня 2012 у Wayback Machine.]
- Design Patterns: Elements of Reusable Object-Oriented Software [ 9 Листопада 2012 у Wayback Machine.]
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Komponuvalnik Composite strukturnij shablon yakij ob yednuye ob yekti v iyerarhichnu derevopodibnu strukturu i dozvolyaye unifikovane zvertannya dlya kozhnogo elementa dereva PriznachennyaDozvolyaye koristuvacham buduvati skladni strukturi z prostishih komponentiv Proyektuvalnik mozhe zgrupuvati dribni komponenti dlya formuvannya bilshih yaki v svoyu chergu mozhut stati osnovoyu dlya stvorennya she bilshih StrukturaKlyuchem do patternu komponuvalnik ye abstraktnij klas yakij ye odnochasno i primitivom i kontejnerom Component U nomu ogolosheni metodi specifichni dlya kozhnogo vidu ob yekta taki yak Operation i zagalni dlya vsih skladovih ob yektiv napriklad operaciyi dlya dostupu i upravlinnya nashadkami Pidklasi Leaf viznachaye primitivni ob yekti yaki ne ye kontejnerami U nih operaciya Operation realizovana vidpovidno do yih specifichnih potreb Oskilki u primitivnih ob yektiv nemaye nashadkiv to zhoden z cih pidklasiv ne realizuye operaciyi pov yazani z upravlinnya nashadkami Add Remove GetChild Klas Composite skladayetsya z inshih primitivnishih ob yektiv Component Realizovana v nomu operaciya Operation viklikaye odnojmennu funkciyu vidtvorennya dlya kozhnogo nashadka a operaciyi dlya roboti z nashadkami vzhe ne porozhni Oskilki interfejs klasu Composite vidpovidaye interfejsu Component to do skladu ob yekta Composite mozhut vhoditi i inshi taki zh ob yekti UchasnikiComponent Component Ogoloshuye interfejs dlya komponovanih ob yektiv Nadaye vidpovidnu realizaciyu operacij za zamovchuvannyam zagalnu dlya vsih klasiv Ogoloshuye yedinij interfejs dlya dostupu do nashadkiv ta upravlinnya nimi Viznachaye interfejs dlya dostupu do batka komponenta v rekursivnoyi strukturi i pri neobhidnosti realizuye jogo mozhlivist neobov yazkova Leaf Leaf 1 Leaf 2 list Ob yekt togo zh tipu sho i Composite ale bez realizaciyi kontejnernih funkcij Predstavlyaye listovi vuzli kompoziciyi i ne maye nashadkiv Viznachaye povedinku primitivnih ob yektiv v kompoziciyi Vhodit do skladu kontejnernih ob yektiv Composite Composite skladenij ob yekt Viznachaye povedinku kontejnernih ob yektiv u yakih ye nashadki Zberigaye iyerarhiyu komponentiv nashadkiv Realizuye pov yazani z upravlinnya nashadkami kontejnerni operaciyi v interfejsi klasu Component PerevagiKliyenti vikoristovuyut interfejs klasu komponentiv dlya vzayemodiyi z ob yektami u skladnij strukturi Yaksho viklik zdijsnyuyetsya v listok zapit obroblyayetsya bezposeredno Yaksho viklik do Composite vin peresilaye zapit do svoyih dochirnih komponentiv VadiYak tilki derevopodibna struktura viznachena kompozitnij dizajn robit derevo nadto zagalnim U konkretnih vipadkah vazhko obmezhiti komponenti dereva lishe okremimi tipami Dlya zabezpechennya obmezhennya programa povinna spiratisya na perevirki vikonannya chasu oskilki vona ne mozhe vikoristovuvati sistemu tipu movi programuvannya Priklad realizaciyiC Priklad realizaciyi na movi S include lt iostream gt include lt deque gt using namespace std Interfejs komponentiv struct IQuackable virtual IQuackable virtual void print const 0 Konkretni komponenti struct Duck public IQuackable virtual void print const cout lt lt Duck lt lt n struct MallardDuck public Duck virtual void print const cout lt lt Mallard Duck lt lt n struct RedheadDuck public Duck virtual void print const cout lt lt Redhead Duck lt lt n Komponuvalnik Takozh mozhe buti komponentom class Flock public IQuackable protected deque lt IQuackable gt quackers kontejner komponentiv public virtual void print const for size t i 0 i lt quackers size i quackers i gt print psevdo rekursivnij viklik void add IQuackable quacker quackers push back quacker void remove size t i if i lt quackers size quackers erase quackers begin i void main Flock Gang IQuackable gang 3 new MallardDuck new RedheadDuck new MallardDuck dodayemo komponuvalniku komponentiv for int i 0 i lt 3 i Gang add gang i Flock Ducks new Flock for int i 0 i lt 3 i Ducks gt add new Duck Gang add Ducks dodayemo komponuvalnika yak komponent inshogo komponuvalnika Gang print C Priklad realizaciyi na movi S Composite pattern Structural example using System using System Collections Generic namespace DoFactory GangOfFour Composite Structural lt summary gt MainApp startup class for Structural Composite Design Pattern lt summary gt class MainApp lt summary gt Entry point into console application lt summary gt static void Main Create a tree structure Composite root new Composite root root Add new Leaf Leaf A root Add new Leaf Leaf B Composite comp new Composite Composite X comp Add new Leaf Leaf XA comp Add new Leaf Leaf XB root Add comp root Add new Leaf Leaf C Add and remove a leaf Leaf leaf new Leaf Leaf D root Add leaf root Remove leaf Recursively display tree root Display 1 Wait for user Console ReadKey lt summary gt The Component abstract class lt summary gt abstract class Component protected string name Constructor public Component string name this name name public abstract void Display int depth lt summary gt The Composite class lt summary gt class Composite Component private List lt Component gt children new List lt Component gt Constructor public Composite string name base name public void Add Component component children Add component public void Remove Component component children Remove component public override void Display int depth Console WriteLine new String depth name Recursively display child nodes foreach Component component in children component Display depth 2 lt summary gt The Leaf class lt summary gt class Leaf Component Constructor public Leaf string name base name public override void Display int depth Console WriteLine new String depth name Dzherelahttp www dofactory com 29 Kvitnya 2012 u Wayback Machine Design Patterns Elements of Reusable Object Oriented Software 9 Listopada 2012 u Wayback Machine