Wzorzec projektowy fabryka abstrakcyjna - abstract factory

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 4569 razy

Opis wzorca

Wzorzec fabryka abstrakcyjna ma za zadanie udostępnienie jednego interfejsu, za którym mogą stać różne klasy po nim dziedziczące. Metody tych klas mają za zadanie tworzenie (produkowanie) nowych obiektów, które najczęściej będą również interfejsami związanymi z obiektami klas po nich dziedziczących. Koniec końców w tym wzorcu chodzi o to, żeby za jednym interfejsem można było osadzić różne wersje klas produkujących za pomocą tych samych metod różne obiekty.

Przykładowy diagram UML fabryki abstrakcyjenj

Klient wybiera jaki rodzaj interfejsu chce uzyskać np. poprzez podanie informacji o systemie z jakiego korzysta. W zależności od tego tworzony jest odpowiedni interfejs, za którym stoi klasa odpowiedzialna za generowanie obiektów widoków dla danego systemu operacyjnego. Po utworzeniu interfejsu klient korzysta z tych samych metod do generowania widoków dla wybranego systemu. Poniżej zamieszczam prosty diagram UML pokazujący wszystkie te zależności.

Przykładowy diagram UML dla wzorca fabryki abstrakcyjnej
Rys. 1
Przykładowy diagram UML dla wzorca fabryki abstrakcyjnej.

Na powyższym diagramie widać, że użytkownik (program) odwołuje się do interfejsu iFactory, za którym może stać klasa WindowsView lub LinuxView zależnie od tego z jakiego systemu korzysta użytkownik. Metody czysto wirtualne getHomeView oraz getDescriptionView mają za zadanie wygenerować interfejsy do obiektów, za którymi stoją odpowiednie widoki dla danego systemu. I tu mała uwaga metody te zwracają interfejs typu iView, za którym może stać klasa WindowsView lub LinuxView. Interfejsy do obiektów tych klas różnić się będą sposobem ich ustawienia.

Przykładowa implementacja w C++

Prosta implementacja wzorca projektowego w C++:

#include <iostream> #include <string> // Klasa abstrakcyjna View class View{ protected: std::string text; public: View(){}; View(std::string text): text(text){}; virtual void drawView() = 0; }; // Klasa widoku dla systemu Windows class WindowsView : public View{ public: WindowsView(std::string text): View("System Windows\n\n" + text){}; virtual void drawView(){ std::cout<<text; } }; // Klasa widoku dla systemu Linux class LinuxView : public View{ public: LinuxView(std::string text): View("System Linux\n\n" + text){}; virtual void drawView(){ std::cout<<text; } }; // Klasa abstrakcyjna (interfejs) do klas generujących (produkujących) obiekty class iFactory{ public: virtual View* getHomeView() = 0; virtual View* getDescriptionView() = 0; }; // klasa produkująca interfejsy widoków dla systemu Windows class WindowsFactory : public iFactory{ public: virtual View* getHomeView(){ return new WindowsView("Strona domowa"); } virtual View* getDescriptionView(){ return new WindowsView("Strona opisu\n\n"); } }; // klasa produkująca interfejsy widoków dla systemu Linux class LinuxFactory : public iFactory{ public: virtual View* getHomeView(){ return new LinuxView("Strona domowa\n\n"); } virtual View* getDescriptionView(){ return new LinuxView("Strona opisu\n\n"); } }; int main(){ iFactory* factory = NULL; // wskaźnik do interfejsu (klasy abstrakcyjnej) int choose = 0; // zmienna przechowująca wybór platformy przez użytkownika std::cout<<"Wybierz platformę: \n\n"; std::cout<<"Linux [0]\n"; std::cout<<"Windows [1]\n\n"; do{ std::cin>>choose; if(choose != 1 && choose != 0){ std::cout<<"\n\nPodałeś złą wartość, spróbój jeszcze raz:"; } }while(choose != 1 && choose != 0); if(choose == 0){ factory = new LinuxFactory(); // wybrano Linuxa }else{ factory = new WindowsFactory(); // wybrano Windowsa } // tworzę widok strony opisu View* descriptionview = factory->getDescriptionView(); // wyświetlam widok strony opisu descriptionview->drawView(); // tworzę widok strony domowej View* homeview = factory->getHomeView(); // wyświetlam widok strony domowej homeview->drawView(); // sprzątanie if(descriptionview){ delete descriptionview; descriptionview = NULL; } if(homeview){ delete homeview; homeview = NULL; } if(factory){ delete factory; factory = NULL; } std::cin.ignore(1); std::cin.clear(); std::cin.get(); return 0; }

Przykładowy efekt działania programu:

Wybierz platforme:

Linux [0]
Windows [1]

0
System Linux

Strona opisu

System Linux

Strona domowa
Strony powiązane
strony powiązane
  1. sourcemaking.com/design_patterns/abstract_factory - strona z opisem wzorca abstract factory [En]
  2. pl.wikipedia.org - opis wzorca na stronie Wikipedii
Propozycje książek