Narzędzia użytkownika

Narzędzia witryny


fabryka_abstrakcyjna

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

fabryka_abstrakcyjna [2008/04/08 17:04] (aktualna)
mchodkie utworzono
Linia 1: Linia 1:
 +=====Abstract factory pattern (Fabryka abstrakcyjna)=====
 +<code cpp>
 +/​************************************************************************************* ​     ​
 + ​* ​                                                              ​Michał Chodkiewicz ​ *
 + * Wzorzec: ​        ​fabryka abstrakcyjna (abstract factory) ​                         *
 + ​* ​                                                                                  *
 + * Zastosowanie: ​   Wzorzec ten umożliwia łatwe wprowadzanie zmian w zakresie klas   *
 + ​* ​                 używanych w kodzie, co umożliwia pisanie kodu, np: na kilka      * 
 + ​* ​                 platform jednocześnie,​ czy łatwiejsze zmienianie kodu wewnątrz ​  *
 + ​* ​                 klasy bibliotecznej. ​                                            *
 + ​* ​                                                                                  ​* ​  
 + ​* ​  ​Opis: ​         Fabryka abstrakcyjna,​ zwykle tworzona jako interfejs, w języku ​  *
 + ​* ​                 c++ jest implementowana za pomocą klasy abstrakcyjnej. Klasa ta  *
 + ​* ​                 ma wygląd typowej fabryki, jednak jako typy zwracane przez       *
 + ​* ​                 wirtualne metody fabrykujące ma zadeklarowane klasy abstrakcyjne *
 + ​* ​                 reprezentujące interfejsy obiektów zwracanych przez klasy        *
 + ​* ​                 pochodne. W kodzie programu implementuje się dla konkretnych ​    *
 + ​* ​                 zastosowań klasy pochodne od fabryki abstrakcyjnej wytwarzające ​ *
 + ​* ​                 obiekty odpowiednie dla danego systemu czy pliku                 *
 + ​* ​                 konfiguracyjnego. Dzięki temu, że najczęściej fabryka jest       *
 + ​* ​                 tworzona w programie tylko raz, przy zmianie zachowania obiektów *
 + ​* ​                 wystarczy zmodyfikować tą linijkę w kodzie, w której następuje ​  *
 + ​* ​                 przypisanie konkretnej fabryki. ​                                 *
 + ​* ​                                                                                  *
 + ​* ​  ​Przykładowy schemat (schemat opisuje inny przypadek niż kod, dla urozmaicenia):​ *
 + ​* ​  ​Prezentowany jest przypadek programowania dla kilku systemów operacyjnych ​      *
 + ​* ​                                                                                  *
 + ​* ​                 Odczyt schematu: ​                                                *
 + ​* ​                 [Element na początku strzałki] ​                                  *
 + ​* ​                 (d) dziedziczy po                                                *
 + ​* ​                 (w) zawiera wskaźnik/​wskaźniki na                                *
 + ​* ​                 (t) tworzy obiekty klasy                                         *
 + ​* ​                 [Element na który wskazuje strzałka] ​                            *
 + ​* ​              ​_______________ ​              ​______________________ ​               *
 + ​* ​              | KlasaUsera ​ |-------------->​|FabrykaAbstrakcyjna |                *
 + ​* ​              ​|_____________| ​           (w)|____________________| ​               *
 + ​* ​              ​|_____________| ​              ​|____________________| ​               *
 + ​* ​              ​|_____________| ​              | A stworzObiekt()=0 |                *
 + ​* ​                    ​| ​                      ​|____________________| ​               *
 + ​* ​                    ​| ​                         /|\(d) /​|\(d) ​ /​|\(d) ​             *
 + ​* ​                    ​| ​            ​______________| ​     |       ​|________ ​         *
 + ​* ​                    ​| ​    ​_______|__________ __________|_______ ________|_________*
 + ​* ​                    ​| ​    ​|FabrykaUnixowa ​ | |FabrykaDosowa ​  | |FabrykaWindows ​ |*
 + ​* ​   -----------------/​\----|________________| |________________| |________________|*
 + ​* ​   |                |     ​|________________| |________________| |________________|*
 + ​* ​   |                |     |A stworzObiekt()| |A stworzObiekt()| |A stworzObiekt()|*
 + ​* ​   |                |(w)  |________________| |________________| |________________|*
 + ​* ​   |    ___________\|/​_____ ​                          ​| ​                 |        *
 + ​* ​   |    | A (klasa abstr) |                           ​| ​                 |        *
 + ​* ​   |    |_________________| ​                          ​| ​                 |        *
 + ​* ​   |    |_________________| ​                          ​| ​                 |        *
 + ​* ​   |    | zareaguj() ​     |                           ​| ​                 |        *
 + ​* ​   |    |_________________| ​                          ​| ​                 |        *
 + ​* ​   |     /​|\(d) ​ /​|\(d) ​ /​|\(d) ​                      ​| ​                 |        *
 + ​* ​   |(t)___| ​      ​| ​      ​|_______ ​                   |                  |        *
 + ​* ​  ​\|/​__|______ ___|________ _____|______ ​             |                  |        *
 + ​* ​  | AUnix    | | ADos     | | AWindows |              |                  |        *
 + ​* ​  ​|__________| |__________| |__________| ​  ​(t) ​       |                  |        *
 + ​* ​  ​|__________| |__________| |__________|<​-------------/​\-----------------| ​       *
 + ​* ​  ​|zareaguj()| |zareaguj()| |zareaguj()| ​             |                           *
 + ​* ​  ​|__________| |__________| |__________| ​             |                           *
 + ​* ​                    /​|\(t) ​                           |                           *
 + ​* ​                     |________________________________| ​                          *
 + ​* ​                                                                                  *
 + ​*************************************************************************************/​
  
 +/* Przykładowy kod. Przedstawia on rysowanie obiektów w zależności od
 +   ​szybkości procesora */
 +#include <​iostream>//​Biblioteka potrzebna w tym przykładzie
 +using namespace std;// dla wygody, żeby nie pisać wszędzie std
 +
 +// Abstrakcyjny model obiektu graficznego
 +class ObiektGraficznyAbstrakcyjny {
 +   ​protected: ​  
 +      float x_;// położenie na ekranie w osi x
 +      float y_;// położenie na ekranie w osi y
 +   ​public:​
 +         ​virtual void rysujSie()=0;//​ metoda do rysowania obiekt
 +         // poniższe metody są wirtualne, gdyż klasy pochodne nie muszą koniecznie w ten sposób przechowywać
 +         // położenia obiektu, jednak mają już ciała, gdyż to będzie najczęstszy przypadek
 +
 +         // metoda do ustalania położenia obiektu
 +         ​virtual void ustawPozycje(float x, float y){
 +            x_=x;
 +            y_=y;         
 +         }
 +         // metody do pobierania położenia obiektu
 +         ​virtual float podajPozX() {return x_;}
 +         ​virtual float podajPozY() {return y_;}
 +         ​ObiektGraficznyAbstrakcyjny (float x, float y) : x_(x), y_(y){}
 +         ​virtual ~ObiektGraficznyAbstrakcyjny() {}//​wirtualny destruktor, bo są wirtualne funkcje
 +};
 +
 +// Abstrakcyjna fabryka obiektów, służąca za interfejs
 +class FabrykaObiektowGraficznychAbstrakcyjna {
 +   ​public:​
 +         // metoda do tworzenia instancji obiektów
 +         ​virtual ObiektGraficznyAbstrakcyjny * utworzObiekt(float x, float y)=0;
 +         ​virtual ~FabrykaObiektowGraficznychAbstrakcyjna(){}//​wirtualny destruktor, bo są wirtualne funkcje
 +}; 
 +
 +// Konkretny model obiektu graficznego,​ dla wolniejszych komputerów
 +class ObiektGraficznyProsty : public ObiektGraficznyAbstrakcyjny {
 +   ​public:​
 +         // funkcja rysujSie jest mocno okrojona, gdyż to tylko przykład zastosowania
 +         void rysujSie(){
 +            cout<<"​malo wymagajacy model jest rysowany na pozycji: "<<​x_<<",​ "<<​y_<<​endl;​
 +         }
 +         ​ObiektGraficznyProsty (float x, float y):​ObiektGraficznyAbstrakcyjny(x,​y){}
 +};
 +
 +// Konkretny model obiektu graficznego,​ dla szybszych komputerów
 +class ObiektGraficznyTrudny : public ObiektGraficznyAbstrakcyjny {
 +   ​public:​
 +         // funkcja rysujSie jest mocno okrojona, gdyż to tylko przykład zastosowania
 +         void rysujSie(){
 +            cout<<"​BARDZO WYMAGAJACY MODEL JEST RYSOWANY NA POZYCJI: "<<​x_<<",​ "<<​y_<<​endl;​
 +         }
 +         ​ObiektGraficznyTrudny (float x, float y):​ObiektGraficznyAbstrakcyjny(x,​y){}
 +};
 +
 +//Konkretna fabryka obiektów graficznych,​ dla wolnych komputerów
 +class FabrykaObiektowGraficznychProstych : public FabrykaObiektowGraficznychAbstrakcyjna {
 +   ​public:​
 +      // skonkretyzowanie metody
 +      ObiektGraficznyAbstrakcyjny * utworzObiekt(float x, float y) {
 +            return new ObiektGraficznyProsty(x,​y); ​     ​
 +      }
 +};
 +
 +//Konkretna fabryka obiektów graficznych,​ dla szybkich komputerów
 +class FabrykaObiektowGraficznychTrudnych : public FabrykaObiektowGraficznychAbstrakcyjna {
 +   ​public:​
 +      // skonkretyzowanie metody
 +      ObiektGraficznyAbstrakcyjny * utworzObiekt(float x, float y) {
 +            return new ObiektGraficznyTrudny(x,​y); ​     ​
 +      }
 +};
 +
 +// Klasa korzystająca z fabryk
 +class KlasaUzytkowa {
 +   ​private:​
 +      static const int ILE_OBIEKTOW=5;//​ile obiektow graficznych naraz na ekranie maksymalnie
 +      // Wskaznik na fabryke obiektow, tu bedzie podany wskaznik do konkretnej fabryki ​
 +      FabrykaObiektowGraficznychAbstrakcyjna * fabryka_;
 +      ObiektGraficznyAbstrakcyjny * pulaObiektow_[ILE_OBIEKTOW];​ // Tablica obiektow do rysowania
 +   ​public:​
 +      // dla zapełniania tablicy obiektów, zmienna nowa partia mówi czy zmieniać obiekty,
 +      // czy też tworzyć nowe od poczatku
 +      void pobierzNowe(bool nowaPartia){
 +         for (int licznik=0; licznik<​5;​ ++licznik){
 +            ObiektGraficznyAbstrakcyjny * temp=pulaObiektow_[licznik]; ​        
 +            if (temp!=NULL){//​ odtworzenie obiektow w nowych warunkach
 +                  pulaObiektow_[licznik]=fabryka_->​utworzObiekt(temp->​podajPozX(),​ temp->​podajPozY()); ​  
 +                  delete temp;          ​
 +            }
 +            else if (nowaPartia){
 +               ​pulaObiektow_[licznik]=fabryka_->​utworzObiekt(licznik,​ ILE_OBIEKTOW - licznik); ​  
 +            }            ​
 +         ​} ​     ​
 +      }
 +      // dla ustawienia źródła obiektów
 +      void ustawFabryke(FabrykaObiektowGraficznychAbstrakcyjna * nowa_fabryka) {
 +            delete fabryka_;// usunięcie starej fabryki ​           ​
 +            fabryka_=nowa_fabryka; ​  // ustawienie nowej fabryki
 +            pobierzNowe(false);//​żeby od razu zmienić typ przechowywanych obiektów ​  
 +      } 
 +      // dla rysowania obiektów
 +      void rysujObiekty(){
 +         for (int licznik=0; licznik<​ILE_OBIEKTOW;​ ++licznik){
 +            if (pulaObiektow_[licznik]!=NULL){
 +                  pulaObiektow_[licznik]->​rysujSie(); ​     ​
 +            }         
 +         ​} ​     ​
 +      }
 +      // konstruktor
 +      KlasaUzytkowa (FabrykaObiektowGraficznychAbstrakcyjna *nowa_fabryka){
 +            fabryka_=nowa_fabryka; ​     ​
 +      }
 +      // destruktor
 +      ~KlasaUzytkowa(){
 +         for (int licznik=0; licznik<​5;​ ++licznik){
 +            delete pulaObiektow_[licznik];//​ zwolnienie puli obiektów ​     ​
 +         ​} ​        
 +         ​delete fabryka_;// zwolnienie fabryki
 +      }      ​
 +};
 +
 +//Program testowy
 +int main(){
 +      cout<<"​..::​ Uruchamianie programu w trybie wysokiej jakosci grafiki ::​.."<<​endl;​
 +      // Na początek ustawiany bardziej wymagający typ obiektu graficznego
 +      KlasaUzytkowa * testowa=new KlasaUzytkowa(new FabrykaObiektowGraficznychTrudnych);​
 +      testowa->​pobierzNowe(true);//​ Ustawianie przykładowych obiektów
 +      cout<<"​..::​ Rysowanie przykladowych obiektow ::​.."<<​endl;​
 +      testowa->​rysujObiekty();​
 +      //{...} Tutaj okazało się, że niestety maszyna jest za wolna
 +      cout<<"​..::​ Niestety maszyna jest za wolna, przelaczanie w tryb niskiej jakosci::​.."<<​endl;​
 +      testowa->​ustawFabryke(new FabrykaObiektowGraficznychProstych());​
 +      cout<<"​..::​ Rysowanie przykladowych obiektow ::​.."<<​endl;​
 +      testowa->​rysujObiekty();​
 +      cout<<"​..::​ Koniec programu ::​.."<<​endl;​
 +}
 +</​code>​
fabryka_abstrakcyjna.txt · ostatnio zmienione: 2008/04/08 17:04 przez mchodkie