Sunteți pe pagina 1din 4

Factory Method Tip i scop: ablon crea ional; crearea de obiecte f

a preciza exact tipul acestora.

Probleme ntmpinate la crearea unui nou obiect: complexitate sporit (procesul nu se reduce la simpla creare a unui nou obiect): o clasa (tipul) obiectului poate fi creeat dinamic; o obiectul poate fi returnat dintr-un object pool; o obiectul poate fi configurat n diverse moduri; duplicarea codului surs ; informa ii neaccesibile noului obiect; centralizarea managementului duratei de via a obiectelor pentru a asigura un comportament consistent; abstractizare insuficient ; Factory: abstractizarea conceptului de obiect responsabil pentru crearea altor obiecte (produse). Solu ie: cte o metod Factory responsabil pentru crearea unui tip de obiect (produs); metoda Factory poate fi parametrizat , pentru a putea crea mai multe tipuri concrete de produse care implementeaz o aceea i interfa ; metoda Factory poate fi supranc rcat n clasele derivate, pentru a crea o anumit versiune a respectivului produs.

Participan i: Product: define te interfa a obiectului ce va fi creat; ConcreteProduct1: ConcreteProduct2: diverse versiuni (concretiz ri) ale obiectului ce va fi creat; Creator: define te o metod ce returneaz un obiect de tipul Product;

ConcreteCreator1: ConcreteCreator2: suprascrie metoda pentru a returna versiunea dorit obiectului Product. Exemplu:
#include <vector> #include <map> #include <algorithm> #include <string> #include <iostream> using namespace std; // Product class IPizzaNapoletana { public: virtual string name() = 0; void printIngredients() { cout << "Ingredients: "; for_each( ingredients.begin(), ingredients.end(), printString); cout << endl; } protected: vector<string> ingredients; IPizzaNapoletana() { ingredients.push_back("mozzarella"); ingredients.push_back("tomatoes"); } private: static void printString(string s) { cout << s << " "; } }; enum {MarguerittaID, MarinaraID, UnknownPizzaID }; // ConcreteProduct1 class Margueritta : public IPizzaNapoletana { public: Margueritta() { ingredients.push_back("basil"); ingredients.push_back("olive oil"); } string name() { return string("Margueritta"); } }; // ConcreteProduct2 class Marinara : public IPizzaNapoletana { public: Marinara() { ingredients.push_back("olive oil"); ingredients.push_back("garlic"); ingredients.push_back("oregano"); } string name() { return string("Marinara"); } }; // auxiliary classes class IOwen

{ public: virtual void baking( IPizzaNapoletana*& ) = 0; }; class WoodBrickOven : public IOwen { public: void baking( IPizzaNapoletana*& pizza ) { cout << "Pizza " << pizza->name() << " was baked in a wood brick oven" << endl; } }; class ElectricDeckOven : public IOwen { public: void baking( IPizzaNapoletana*& pizza ) { cout << "Pizza " << pizza->name() << " was baked in an electric deck oven" << endl; } }; // Creator class IRestaurant { protected: // specific owen IOwen* pOwen; public: // factory method (default implementation) virtual IPizzaNapoletana* makePizza( int pizzaId ) = 0 { IPizzaNapoletana* tmpPizza = NULL; switch ( pizzaId ) { case MarguerittaID case MarinaraID }

: tmpPizza = new Margueritta; break; : tmpPizza = new Marinara; break;

if ( NULL == tmpPizza ) { cout << "Unknown pizza ID!" << endl; } else { cout << "Name: " << tmpPizza->name() << endl; tmpPizza->printIngredients(); } return tmpPizza; } }; // ConcreteCreator1 class Domneasca : public IRestaurant { map<int, int> pizzaPrice; public: Domneasca() { pOwen = new WoodBrickOven; pizzaPrice.insert( pair<int,int>( MarguerittaID, 22 ) ); pizzaPrice.insert( pair<int,int>( MarinaraID, 20 ) ); } // factory method (concrete implementation) IPizzaNapoletana* makePizza( int pizzaId ) { // use default implementation IPizzaNapoletana* tmpPizza = IRestaurant::makePizza( pizzaId );

if ( NULL != tmpPizza ) { // restaurant specific baking pOwen->baking(tmpPizza); // show me the money! cout << "Price: " << pizzaPrice.find(pizzaId)->second << endl; cout << endl; } return tmpPizza; } }; // ConcreteCreator2 class Hot : public IRestaurant { vector<int> pizzaPrice; public: Hot() { pOwen = new ElectricDeckOven; // Margueritta pizzaPrice.push_back( 28); // Marinara pizzaPrice.push_back( 24); } // factory method (concrete implementation) IPizzaNapoletana* makePizza( int pizzaId ) { // use default implementation IPizzaNapoletana* tmpPizza = IRestaurant::makePizza( pizzaId ); if ( NULL != tmpPizza ) { // restaurant specific baking pOwen->baking(tmpPizza); // show me the money! cout << "Price: " << pizzaPrice[pizzaId] << endl; cout << endl; } return tmpPizza; } }; int main() { Domneasca restaurant1; IPizzaNapoletana* pizza1 = restaurant1.makePizza( MarguerittaID ); IPizzaNapoletana* pizza2 = restaurant1.makePizza( MarinaraID ); Hot restaurant2; IPizzaNapoletana* pizza3 = restaurant2.makePizza( MarguerittaID ); IPizzaNapoletana* pizza4 = restaurant2.makePizza( MarinaraID ); IPizzaNapoletana* pizza5 = restaurant2.makePizza( UnknownPizzaID ); return 0; }

S-ar putea să vă placă și