Wzorzec projektowy fabryka abstrakcyjna - abstract factory
Stronę tą wyświetlono już: 3394 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.
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

Tytuł:
React 17. Wzorce projektowe i najlepsze praktyki. Projektowanie i rozwijanie nowoczesnych aplikacji internetowych. Wydanie III
Autor:
Carlos Santana Roldán

Tytuł:
Wzorce projektowe. Rusz głową! Tworzenie rozszerzalnego i łatwego w utrzymaniu oprogramowania obiektowego. Wydanie II
Autor:
Eric Freeman, Elisabeth Robson

Tytuł:
Wzorce projektowe w .NET Core 3. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#
Autor:
Dmitri Nesteruk

Tytuł:
Wzorce projektowe. Elementy oprogramowania obiektowego wielokrotnego użytku
Autor:
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

Tytuł:
Projektowanie interfejsów., Sprawdzone wzorce projektowe. Wydanie III
Autor:
Jenifer Tidwell, Charles Brewer, Aynne Valencia-Brooks

Tytuł:
Kubernetes. Wzorce projektowe. Komponenty wielokrotnego użycia do projektowania natywnych aplikacji chmurowych
Autor:
Bilgin Ibryam, Roland Huß

Tytuł:
Wzorce projektowe w .NET. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#
Autor:
Dmitri Nesteruk

Tytuł:
Programowanie zorientowane obiektowo. Wzorce projektowe. Wydanie II
Autor:
Alan Shalloway, James R. Trott

Tytuł:
Java EE 8. Wzorce projektowe i najlepsze praktyki
Autor:
Rhuan Rocha, Joao Purificacao

Tytuł:
Systemy reaktywne. Wzorce projektowe i ich stosowanie
Autor:
Roland Kuhn Dr., Brian Hanafee, Jamie Allen