Metoda wytwórcza

Przeznaczenie

Wzorzec ten określa interfejs do tworzenia obiektów, lecz umożliwia podklasom decydowanie o tym, której klasy ma to być obiekt. Dzięki Metodzie Wytwórczej klasy mogą zdać się na podklasy w kwestii tworzenia egzemplarzy.

Przykład: Zrąb aplikacji MDI.

Stosowalność metod wytwórczych

  • klasa nie może przewidzieć, jakich klas obiekty musi tworzyć
  • klasa chce, by to jej podklasy specyfikowały tworzone przez nią obiekty
  • klasy przekazuj? odpowiedzialność jednej z kilku podklas pomocniczych, a Ty chcesz tylko w jednym miejscu ustalić, która z podklas pomocniczych jest ich delegatem

Struktura metody wytwórczej

Metoda wytwórcza - implementacja

Dwa główne typy wzorca:
z abstrakcyjnym twórcą ? wymaga implementacji podklas dla konkretnych obiektów
z domyślną implementacją metody tworzącej

Pozwala na łączenie kilku hierarchii klas (np. produkty i obiekty manipulujące)

Typy klas można parametryzować poprzez argumenty wejściowe metod wytwórczych

Implementacja metod wytwórczych zależy od wykorzystywanego języka programowania

Zastosowanie

  • Metoda wytwórcza jest najczęściej stosowanym wzorcem w szkieletach aplikacji
  • Najczęściej metodę wytwórczą można wykorzystać w implementacji fabryki abstrakcyjnej
  • Większość sterowników, interfejsów, pakietów komponentów realizuje scenariusz inicjalizacji jak metodę wytwórczą

Implementacja

#include 
#include 
#include  // std::auto_ptr
class Pizza {
public:
    virtual void get_price() const = 0;
    virtual ~Pizza() {};
};
 
class HamAndMushroomPizza: public Pizza {
public:
    virtual void get_price() const {
        std::cout << "Ham and Mushroom: $8.5" << std::endl;
    }
};
 
class DeluxePizza : public Pizza {
public:
    virtual void get_price() const {
        std::cout << "Deluxe: $10.5" << std::endl;
    }
};
 
class HawaiianPizza : public Pizza {
public:
    virtual void get_price() const {
        std::cout << "Hawaiian: $11.5" << std::endl;
    }
};
 
class PizzaFactory {
public:
    static Pizza* create_pizza(const std::string& type) {
        if (type == "Ham and Mushroom")
            return new HamAndMushroomPizza();
        else if (type == "Hawaiian")
            return new HawaiianPizza();
        else
            return new DeluxePizza();
    }
};
//usage
int main() {
    PizzaFactory factory;
 
    std::auto_ptr pizza(factory.create_pizza("Default"));
    pizza->get_price();
 
    pizza.reset(factory.create_pizza("Ham and Mushroom"));
    pizza->get_price();
 
    pizza.reset(factory.create_pizza("Hawaiian"));
    pizza->get_price();
}