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)
// 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 { public:
virtual Product* CreateProduct();
};
template <class TheProduct>
Product* StandardCreator<TheProduct>::CreateProduct () {
return new TheProduct;
}
class MyProduct : public Product { public:
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/