Obiektowe metody projektowania systemów Factory Method design pattern (aka. Virtual Constructor)
Wstęp: Factory Method – wzorzec kreacyjny pracujący w zakresie klasowym Intencja – Zdefiniować interfejs dla tworzenia obiektu, ale pozwolić podklasom skonkretyzować, którą klasę instancjalicować.
Plan: Powody utworzenia, motywacja Zastosowanie Przykłady implementacji w C++ Struktura i elementy składowe Konsekwencje użycia Powiązania z innymi wzorcami Bibliografia
Powody utworzenia, motywacja Fabryki obiektów, a operator new Znajomość tylko klasy abstrakcyjnej Ale tworzenie podklas konkretnych Zrzucenie odpowiedzialności na potomka Przykład: uelestyczniene frameworks
Zastosowanie Implementacja klasy nie zawiera informacji o tym co dokładnie tworzymy tylko kiedy. Klasa wymaga by jej podklasy wyspecyfikowały jaki obiekt będzie potrzebny. Klasa oddelegowuje odpowiedzialność do jednej z klas pomocniczych.
Przykłady implementacji w C++ (parametryzowane factory method) class Creator { public: virtual Product* Create(ProductId); }; Product* Creator::Create (ProductId id) { if (id == MOJE) return new MyProduct; if (id == TWOJE) return new YourProduct; // i.t.d. dla innych produktów... return 0; } Product* MyCreator::Create (ProductId id) { if (id == TWOJE) return new MyProduct; if (id == MOJE) return new YourProduct; // N.B.: zamieniłem TWOJE i MOJE if (id == ICH) return new TheirProduct; return Creator::Create(id); // wywołane jeśli wszystko inne zawiedzie
Przykłady implementacji w C++ (użycie szablonów) // Użycie szablonów by uniknąć podklasowywania. class Creator { public: virtual Product* CreateProduct() = 0; }; template <class TheProduct> class StandardCreator: public Creator { virtual Product* CreateProduct(); Product* StandardCreator<TheProduct>::CreateProduct () { return new TheProduct; } class MyProduct : public Product { MyProduct(); // ... StandardCreator<MyProduct> myCreator;
Struktura i elementy składowe
Konsekwencje użycia Zalety. W kodzie nie musimy zawierać odwołań do specyficznych dla zastosowania klas. Kod jest abstrakcyjny i ogólny, ale działa na konkretnych, zdefiniowanych przez użytkownika klasach produkowanych.
Konsekwencje użycia Zalety. Możemy zaimplementować tworzenie domyślnego produktu, ale dać przy tym użytkownikowi możliwość podstawienia swojej wyspecjalizowanej wersji. (np.. CreateFileDialog zamiast zwykłego dialogu otwarcia pliku da nam dialog z podglądem pliku graficznego)
Konsekwencje użycia I wady… Potrzeba podklasowania Creator dla każdego kolejnego ConcreteProduct. Chyba, że użyjemy szablonów…
Powiązania z innymi wzorcami Abstract Factory jest często implementowane z wykorzystaniem Factory Method. Jest to eleganckie i czytelne rozwiązanie. Prototype – podobieństwa i różnice Metody-fabryki są często wywoływane z Template Method.
Podsumowanie: Klasa Creator pozwala podklasom zdefiniować konkretna metodę-fabrykę, a ona produkuje konkretny produkt, będący elementem pewnej nadklasy. Dostajemy wysoce elastyczny i elegancki, czytelny kod, choć czasem tę samą funkcjonalność możnaby uzyskać żonglując konstruktorami.
Bibliografia: Gamma E.,Helm R.,Johnson R., Vlissides J.: Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995 http://c2.com/cgi/wiki?FactoryMethod http://hillside.net/patterns/ http://en.wikipedia.org/wiki/Factory_method_pattern Alexandrescu A.: Modern C++ Design, Addison-Wesley, 2001 http://sourceforge.net/projects/loki-lib/
...i to by było tyle na dzisiaj!