Composite Pattern – lucrul unitar cu structuri ierarhice (ex: meniu, fișiere) – C# / .NET
În multe aplicații .NET apare nevoia de a lucra cu structuri ierarhice: meniuri, directoare și fișiere, componente UI, noduri într-un arbore, categorii de produse etc.
Problema? Uneori trebuie să tratezi obiectele individuale și grupurile de obiecte în același mod.
Aici intervine Composite Pattern, un pattern structural care permite tratarea uniformă a obiectelor simple și a celor compuse. Acesta modelează structuri “arbore” astfel încât clienții să nu fie obligați să știe dacă lucrează cu o frunză sau cu un nod compus.
🎯 De ce este util Composite Pattern
Composite este ideal când avem:
-
structuri arborescente (meniuri, file system, categorii)
-
obiecte care pot conține alte obiecte
-
nevoie de operații uniforme pentru elemente simple și compuse
-
scenarii de recursivitate
Scopul: uniformizare + simplitate.
Clientul apelează aceleași metode, indiferent de tipul nodului.
🧱 Structura Composite Pattern
-
Component — interfața comună pentru toate obiectele din arbore
-
Leaf — obiect individual (ex: fișier, element meniu)
-
Composite — conține alte componente (ex: director, meniu principal)
🧩 Exemplu simplu în C#
Să modelăm un sistem de meniuri:
🟦 Component – interfața comună
public interface IMenuComponent
{
string Name { get; }
void Display(int depth = 0);
}
🟩 Leaf – element simplu de meniu
public class MenuItem : IMenuComponent
{
public string Name { get; }
public MenuItem(string name)
{
Name = name;
}
public void Display(int depth = 0)
{
Console.WriteLine(new string('-', depth) + Name);
}
}
🟧 Composite – grup de elemente
public class MenuGroup : IMenuComponent
{
public string Name { get; }
private readonly List<IMenuComponent> _children = new();
public MenuGroup(string name)
{
Name = name;
}
public void Add(IMenuComponent component) => _children.Add(component);
public void Remove(IMenuComponent component) => _children.Remove(component);
public void Display(int depth = 0)
{
Console.WriteLine(new string('-', depth) + Name);
foreach (var child in _children)
child.Display(depth + 2);
}
}
▶️ Utilizare
var mainMenu = new MenuGroup("Meniu Principal");
var fileMenu = new MenuGroup("Fișier");
var editMenu = new MenuGroup("Editare");
fileMenu.Add(new MenuItem("Nou"));
fileMenu.Add(new MenuItem("Deschide"));
fileMenu.Add(new MenuItem("Salvează"));
editMenu.Add(new MenuItem("Copiere"));
editMenu.Add(new MenuItem("Lipire"));
mainMenu.Add(fileMenu);
mainMenu.Add(editMenu);
mainMenu.Display();
📌 Output:
Meniu Principal
--Fișier
----Nou
----Deschide
----Salvează
--Editare
----Copiere
----Lipire
Structura se poate extinde recursiv, fără schimbări în codul client.
✔️ Beneficii
-
tratament unitar pentru obiecte simple și compuse
-
extindere facilă (adaugă noduri noi fără a schimba codul existent)
-
modelează elegant structurile arbore
-
reduce codul duplicat
❗ Dezavantaje
-
poate ascunde diferențele între noduri (dacă unele nu ar trebui să aibă copii)
-
crește numărul de clase
-
unele operații pot fi nepotrivite pentru nodurile „leaf”
🔚 Concluzie
Composite Pattern este excelent pentru aplicații care gestionează structuri ierarhice complexe și permite manipularea lor într-un mod elegant, uniform și scalabil. Este des folosit în UI frameworks, sisteme de meniuri, editori grafici, file systems, cataloguri de produse etc.
