Wzorzec projektowy fabryka abstrakcyjna - abstract factory

Stronę tą wyświetlono już: 158 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++:

Listing 1
  1. #include <iostream>
  2. #include <string>
  3. // Klasa abstrakcyjna View
  4. class View{
  5. protected:
  6. std::string text;
  7. public:
  8. View(){};
  9. View(std::string text): text(text){};
  10. virtual void drawView() = 0;
  11. };
  12. // Klasa widoku dla systemu Windows
  13. class WindowsView : public View{
  14. public:
  15. WindowsView(std::string text): View("System Windows\n\n" + text){};
  16. virtual void drawView(){
  17. std::cout<<text;
  18. }
  19. };
  20. // Klasa widoku dla systemu Linux
  21. class LinuxView : public View{
  22. public:
  23. LinuxView(std::string text): View("System Linux\n\n" + text){};
  24. virtual void drawView(){
  25. std::cout<<text;
  26. }
  27. };
  28. // Klasa abstrakcyjna (interfejs) do klas generujących (produkujących) obiekty
  29. class iFactory{
  30. public:
  31. virtual View* getHomeView() = 0;
  32. virtual View* getDescriptionView() = 0;
  33. };
  34. // klasa produkująca interfejsy widoków dla systemu Windows
  35. class WindowsFactory : public iFactory{
  36. public:
  37. virtual View* getHomeView(){
  38. return new WindowsView("Strona domowa");
  39. }
  40. virtual View* getDescriptionView(){
  41. return new WindowsView("Strona opisu\n\n");
  42. }
  43. };
  44. // klasa produkująca interfejsy widoków dla systemu Linux
  45. class LinuxFactory : public iFactory{
  46. public:
  47. virtual View* getHomeView(){
  48. return new LinuxView("Strona domowa\n\n");
  49. }
  50. virtual View* getDescriptionView(){
  51. return new LinuxView("Strona opisu\n\n");
  52. }
  53. };
  54. int main(){
  55. iFactory* factory = NULL; // wskaźnik do interfejsu (klasy abstrakcyjnej)
  56. int choose = 0; // zmienna przechowująca wybór platformy przez użytkownika
  57. std::cout<<"Wybierz platformę: \n\n";
  58. std::cout<<"Linux [0]\n";
  59. std::cout<<"Windows [1]\n\n";
  60. do{
  61. std::cin>>choose;
  62. if(choose != 1 && choose != 0){
  63. std::cout<<"\n\nPodałeś złą wartość, spróbój jeszcze raz:";
  64. }
  65. }while(choose != 1 && choose != 0);
  66. if(choose == 0){
  67. factory = new LinuxFactory(); // wybrano Linuxa
  68. }else{
  69. factory = new WindowsFactory(); // wybrano Windowsa
  70. }
  71. // tworzę widok strony opisu
  72. View* descriptionview = factory->getDescriptionView();
  73. // wyświetlam widok strony opisu
  74. descriptionview->drawView();
  75. // tworzę widok strony domowej
  76. View* homeview = factory->getHomeView();
  77. // wyświetlam widok strony domowej
  78. homeview->drawView();
  79. // sprzątanie
  80. if(descriptionview){
  81. delete descriptionview;
  82. descriptionview = NULL;
  83. }
  84. if(homeview){
  85. delete homeview;
  86. homeview = NULL;
  87. }
  88. if(factory){
  89. delete factory;
  90. factory = NULL;
  91. }
  92. std::cin.ignore(1);
  93. std::cin.clear();
  94. std::cin.get();
  95. return 0;
  96. }

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

Komentarze