Kolejnym omawianym wzorcem projektowym jest Kompozyt (Composite). Kompozyt to grupa obiektów, z których każdy może zawierać inne obiekty. Zatem każdy obiekt, może być grupą obiektów lub pojedynczym obiektem czyli liściem. Wzorzec kompozyt oparty jest o strukturę drzewiastą.
Kompozyt jak i Liść dziedziczy po tym samym interfejsie Komponent co pozwala na dostęp do obiektów tak samo jak do grupy tych obiektów. Możemy wykonywać operacje na pojedynczym obiekcie, jak i na grupie obiektów stosując ten wzorzec.
Przykład implementacji:
public interface Komponent
{
void Operacja();
}
public class Lisc : Komponent
{
public void Operacja()
{
Console.WriteLine("Liść");
}
}
public class Kompozyt : Komponent
{
private List komponenty = new List();
public void Operacja()
{
Console.WriteLine("Kompozyt{");
foreach (var komponent in komponenty)
{
komponent.Operacja();
}
Console.WriteLine("}");
}
public void Dodaj(Komponent komponent)
{
komponenty.Add(komponent);
}
public void Usun(Komponent komponent)
{
komponenty.Remove(komponent);
}
}
Liść i Kompozyt dziedziczą po interfejsie Komponent, oba obiekty maja zdefiniowaną metodę Operacja. Obiekt Kompozyt zawiera listę obiektów Komponent oraz dodatkowe metody Dodaj i Usun.
Uruchomienie przykładu, tworzymy kilka obiektów prostych Lisc oraz obiekty Kompozyt, które zawierają obiekty Lisc oraz drugi obiekt Kompozyt, który zawiera pojedyncze obiekty Lisc jak i obiekt Kompozyt.
class Program
{
static void Main(string[] args)
{
Lisc lisc = new Lisc();
Lisc lisc2 = new Lisc();
Kompozyt kompozyt = new Kompozyt();
kompozyt.Dodaj(lisc);
kompozyt.Dodaj(lisc2);
kompozyt.Dodaj(new Lisc());
Kompozyt kompozyt2 = new Kompozyt();
kompozyt2.Dodaj(lisc);
kompozyt2.Dodaj(kompozyt);
kompozyt2.Dodaj(lisc2);
kompozyt2.Operacja();
Console.ReadKey();
}
}
Wynik programu:
Kompozyt{
Liść
Kompozyt{
Liść
Liść
Liść
}
Liść
}
Podsumowanie
Wzorzec Kompozyt najlepiej sprawdzi się do zarządzenia grupą podobnych obiektów, na której możemy wykonać podobne operacje. Przez jedno wywołanie metody możemy sterować pojedynczym obiektem jak i całą grupą obiektów. Daje to wrażenie, że odwołujemy się do pojedynczego obiektu, gdy faktycznie działamy na grupie obiektów.