Wzorce projektowe (13)

Autor: Damian Chodorek • Opublikowany: 24 lipca 2015 • Kategoria: kursy, wzorce projektowe

Kompozyt.

Kompozyt to wzorzec obiektowy. Jego celem jest składanie wielu obiektów w taki sposób, aby klient widział je jako pojedynczy obiekt, innymi słowy – zorganizowanie obiektów hierarchicznie, tak aby jednakowo naturalnie wykonywać operacje zarówno na pojedynczym obiekcie (liściu) jak i całej grupie(węźle).

Klasy

class Component{/*
to klasa abstrakcyjna dla liści oraz kompozytów;
definiuje interfejs, który musi implementować klasa liści oraz kompozytów, np. metody kopiuj, wklej, zmień nazwę - powinny je posiadać pliki (liście) i foldery (kompozyty) 
*/};

class Leaf: public Component{/*
klasa obiektów, które nie mają dzieci
*/};

class Composite: public Component{/*
jest węzłem gromadzącym potomków oraz implementującym operacje działające na nich;
potomkiem kompozytu może być inny kompozyt
*/};

class Client{/*
klient manipuluje hierarchiami obiektów za pomocą interfejsu kompozytu
*/};

Etapy działania

  1. Klient tworzy obiekt kompozytu.
  2. Tworzy i dodaje do kompozytu obiekty liści lub inny kompozyt.
  3. Na kompozycie wykonuje metody, a ten odpowiada za to, by były wykonane poprawnie dla całej hierarchii.

Konsekwencje

  • Możliwość wykonania operacji w prosty sposób na całej grupie obiektów.
  • Kod klienta staje się bardziej przejrzysty i łatwiejszy w zrozumieniu.
  • Dodawanie nowych obiektów jest proste, klient nie musi zmieniać swojego kodu.

Przykład

#include <vector>
#include <iostream>
using namespace std;

///abstrakcyjna klasa kształtów
class Ksztalt
{
public:
    virtual void wyswietl()=0;
    virtual void zaznacz()=0;
    virtual void kopiuj()=0;
    virtual void wklej()=0;
};

///klasa reprezentująca linie
class Linia: public Ksztalt
{
public:
    void wyswietl(){ cout<<"wyswietlam linie"<<endl; }
    void zaznacz() { cout<<"zaznaczam linie"<<endl; }
    void kopiuj() {cout<<"kopiuje linie"<<endl; }
    void wklej() { cout<<"wklejam linie"<<endl;}
};

///klasa reprezentująca kwadrat
class Kwadrat: public Ksztalt
{
public:
    void wyswietl(){ cout<<"wyswietlam kwadrat"<<endl; }
    void zaznacz() { cout<<"zaznaczam kwadrat"<<endl; }
    void kopiuj() {cout<<"kopiuje kwadrat"<<endl; }
    void wklej() { cout<<"wklejam kwadrat"<<endl;}
};

///klasa reprezentuje złożony kształt,
///który może się składać z kilku podstawowych
class zlozonyKsztalt : public Ksztalt
{
public:
    void wyswietl()
    {
        cout<<"wyswietlam elementy skladowe:"<<endl;
        for(unsigned int i=0; i<_lista.size(); ++i)
        {
            _lista[i]->wyswietl();
        }
    }

    void zaznacz()
    {
        cout<<"zaznaczam elementy skladowe:"<<endl;
        for(unsigned int i=0; i<_lista.size(); ++i)
        {
            _lista[i]->zaznacz();
        }
    }

    void kopiuj()
    {
        cout<<"kopiuje elementy skladowe:"<<endl;
        for(unsigned int i=0; i<_lista.size(); ++i)
        {
            _lista[i]->kopiuj();
        }
    }

    void wklej()
    {
        cout<<"wklejam elementy skladowe:"<<endl;
        for(unsigned int i=0; i<_lista.size(); ++i)
        {
            _lista[i]->wklej();
        }
    }

    void dodaj(Ksztalt* obj)
    {
        _lista.push_back(obj);
    }

private:
    std::vector<Ksztalt *> _lista;
};

///kompozyt
class Kompozyt: public Ksztalt
{
public:
    void wyswietl()
    {
        for(unsigned int i=0; i<_lista.size(); ++i)
        {
            _lista[i]->wyswietl();
        }
    }

    void zaznacz()
    {
        for(unsigned int i=0; i<_lista.size(); ++i)
        {
            _lista[i]->zaznacz();
        }
    }
	
    void kopiuj()
    {
        for(unsigned int i=0; i<_lista.size(); ++i)
        {
            _lista[i]->kopiuj();
        }
    }
	
    void wklej()
    {
        for(unsigned int i=0; i<_lista.size(); ++i)
        {
            _lista[i]->wklej();
        }
    }

    void dodaj(Ksztalt* obj)
    {
        _lista.push_back(obj);
    }

private:
    std::vector<Ksztalt*> _lista;
};


int main(int argc, const char* argv[])
{
    Kompozyt wszystkieKsztalty;

    Linia linia1;
    Linia linia2;

    wszystkieKsztalty.dodaj(&linia1);
    wszystkieKsztalty.dodaj(&linia2);

    Kwadrat kwadrat1;

    wszystkieKsztalty.dodaj(&kwadrat1);

    zlozonyKsztalt zK;

    Linia linia3;
    Kwadrat kwadrat2;

    zK.dodaj(&linia3);
    zK.dodaj(&kwadrat2);

    wszystkieKsztalty.dodaj(&zK);

    wszystkieKsztalty.wyswietl();

    return 0;
}

część 14

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.