Autor podstrony: Krzysztof Zajączkowski

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

Opis wzorca projektowego pyłek

Wzorzec projektowy pyłek należy do wzorców strukturalnych. Wzorzec ten umożliwia wydzielenie części wspólnej dla wielu obiektów i przechowywanie jej w jednym oddzielnym obiekcie, do którego obiekt główny odwołuje się poprzez wskaźnik. Ten wzorzec można wykorzystać w grze komputerowej, gdzie obiekty tej samej klasy mają przypisaną taką samą teksturę. Tekstury zawsze ważą sporo i zajmują sporo miejsca w pamięci więc aby zapobiec niepotrzebnemu ich powielaniu tworzy się specjalną klasę, gdzie przechowywane są obiekty tekstur. Dany obiekt w grze np. czołg określonego typu odwołuje się do znajdującego się pod wskazanym adresem obiektu tekstury. W ten sposób mogę utworzyć dowolną liczbę czołgów danego typu, dla których wykorzystywana będzie jedna i ta sama tekstura.

Przykładowy diagram UML wzorca projektowego pyłek

Poniższy diagram pokazuje zlepek wykorzystania trzech różnych wzorców projektowych:

Obiekt klasy Textures jest dostępny globalnie z poziomu metody statycznej getTextures i globalnie udostępnia możliwość dodawania nowych tekstur, które z kolei dodawane są przez obiekty klas M1A1_Abrams_tank i T34_tank.

Przykład diagramy UML wzorca projektowego pyłek
Rys. 1
Przykład diagramy UML wzorca projektowego pyłek, który wykorzystuje również wzorzec projektowy singleton oraz wzorzec projektowy metoda wytwórcza

Przykładowa implementacja wzorca projektowego pyłek w C++

#include <iostream> #include <string> #include <map> class Texture{ std::string texture; public: Texture(std::string path){ texture = "Texture created from: "; texture += path; std::cout << "Created new Texture from path: " << path << std::endl << std::endl; } void draw() const { std::cout << texture << std::endl << std::endl; } }; class Textures{ std::map<std::string, Texture*> textures; Textures(){ std::cout<<"Konstruktor textures"<<std::endl<<std::endl; } public: Texture* addTexture(std::string textureName, std::string texturePath){ std::map<std::string, Texture*>::iterator findTexture = textures.find(textureName); if(findTexture == textures.end()){ Texture* newTexture = new Texture(texturePath); this->textures[textureName] = newTexture; return newTexture; } std::cout << "Texture \apos" << textureName << "\apos already exist so I return existing texture!" << std::endl << std::endl; return findTexture->second; } Texture* getTexture(std::string textureName){ std::map<std::string, Texture*>::iterator findTexture = textures.find(textureName); if(findTexture == textures.end()){ return NULL; } return findTexture->second; } ~Textures(){ for(std::map<std::string, Texture* >::iterator texture = textures.begin(); texture != textures.end(); texture){ if(texture->second){ delete texture->second; texture->second = NULL; } } textures.clear(); } static Textures& getTextures() { static Textures textures; return textures; } }; class iTank{ protected: Texture* texture; std::string tankType; public: virtual void draw() const = 0; }; class M1A1_Abrams_tank : public iTank{ public: M1A1_Abrams_tank(){ tankType = "M1A1 Abrams"; texture = Textures::getTextures().addTexture("M1A1 Abrams tank", "tank_textures/M1A1_Abrams_tank.gif"); } virtual void draw() const { std::cout<<"Draw tank: " << tankType << std::endl << std::endl; if(texture){ texture->draw(); } } }; class T34_tank : public iTank{ public: T34_tank(){ tankType = "T34"; texture = Textures::getTextures().addTexture("T34 tank", "tank_textures/T34_tank.gif"); } virtual void draw() const { std::cout<<"Draw tank: " << tankType << std::endl << std::endl; if(texture){ texture->draw(); } } }; class TankFactory{ public: static iTank* createTank(std::string tankType){ if(tankType == "T34"){ return new T34_tank; } if(tankType == "M1A1 Abrams"){ return new M1A1_Abrams_tank; } return NULL; } }; int main(){ iTank* M1A1_Abrams_1 = TankFactory::createTank("M1A1 Abrams"); iTank* M1A1_Abrams_2 = TankFactory::createTank("M1A1 Abrams"); iTank* T34 = TankFactory::createTank("T34"); std::cin.get(); return 0; }

Wynik działania powyższego kodu:

Konstruktor textures

Created new Texture from path: tank_textures/M1A1_Abrams_tank.gif

Texture "M1A1 Abrams tank" already exist so I return existing texture!

Created new Texture from path: tank_textures/T34_tank.gif

Strony powiązane
strony powiązane
  1. sourcemaking.com/design_patterns/flyweight - strona opisująca wzorzec projektowy pyłek [En]
  2. pl.wikipedia.org - opis tego wzorca na stronie Wikipedii
Layout wykonany przez autora strony, wszelkie prawa zastrzeżone. Jakiekolwiek użycie części lub całości grafik znajdujących się na tej stronie bez pisemnej zgody jej autora surowo zabronione.