C++ Factory Design Pattern:
It defines an interface for creating an object but let subclass decide which class to instantiate. Subclass will create a object. This design pattern comes under creational design pattern.
In layman language:
We have factory that will give us final product and we have given all creation responsibility to factory.
Example:
We want a shoes so we need to create shoes factory and its subclass will create actual shoes based on type like if type is sport then subclass will create sports shoes, if type is causal then subclass will create causal shoes and so on. we can extend this design in future by adding new type or adding new sub class.
Class Diagram:
There are 3 part:
- Client: It has Factory instance, it will order to Factory to create a product.
- Factory: It is an abstract class, final product will be created by subclass based on type.
- Product: It is an abstract class, sub-classes are all concrete product.
When will we use Factory Method:
When we want to create a single object of different types and there is possibility we might add new type of object in future.
Why will we use Factory Method:
Because Factory method takes all creation responsibility from client and give the final object to client and its very easy to extend in future. If we extend it in future to add new object then we need to do very small change in client side (it will not pollute the client code).
It is very easy to extend to support new object.
Note: Factory Design pattern is perfect example of “Dependency Inversion” design principle because client depends upon API of abstract factory and derived class of factory is also depend upon API of abstract factory so both depend upon abstraction of factory class.
Class Diagram of Factory Pattern:
Class Diagram of Real Example:
source code with factory method example in c++11:
/* * File:factory.cpp * This file is described the Factory Design Pattern with help of example * Author: Alpha Master * Date: 18 April 2021 */ //Header File #include<iostream> #include<memory> //Pizza class Pizza { public: virtual void BakePizza()=0; virtual void PackPizza()=0; }; class DominoPanerrPiza : public Pizza { public: void BakePizza() { std::cout<<"DominoPanerrPiza is ready"<<std::endl; } void PackPizza() { std::cout<<"DominoPanerrPiza is packed"<<std::endl; } }; class DominoCheesePiza : public Pizza { public: void BakePizza() { std::cout<<"DominoCheesePiza is ready"<<std::endl; } void PackPizza() { std::cout<<"DominoCheesePiza is packed"<<std::endl; } }; //class PizzaFactory class PizzaFactory { protected: std::unique_ptr<Pizza>_mPizza; public: Pizza* GetPizza(std::string type) { _mPizza.reset(CreatePizza(type)); return _mPizza.release(); } private: virtual Pizza* CreatePizza(std::string type)=0; }; //DominoPizzaFactory class DominoPizzaFactory:public PizzaFactory { private: Pizza* CreatePizza(std::string type) { Pizza* pz = nullptr; if(type == "Paneer") pz = new DominoPanerrPiza; else if (type == "Cheese") pz = new DominoCheesePiza; else nullptr; return pz; } }; //Client int main() { std::cout<<"In Main"<<std::endl; //Select Factory std::unique_ptr<PizzaFactory>ptr{nullptr}; ptr.reset(new DominoPizzaFactory); //Order the Pizza with type std::cout<<"Ordering Paneer Pizza from Domino"<<std::endl; std::unique_ptr<Pizza>upPz{nullptr}; upPz.reset(ptr->GetPizza("Paneer")); upPz->BakePizza(); upPz->PackPizza(); std::cout<<"!!!!!!!!!!Got the Pizza!!!!!!!!!"<<std::endl; return 0; }
Output:
In Main Ordering Paneer Pizza from Domino DominoPanerrPiza is ready DominoPanerrPiza is packed !!!!!!!!!!Got the Pizza!!!!!!!!!