//FACTORY METHOD ------------------------------------------------------------------------------- // | GROUP // |  | creational // | INTENT // |  | interface for creating an object // |  |  | defers instantiation to subclasses // |  | subclasses decide which class to instantiate // | BENEFITS // |  | aspects of the code that may vary // |  |  | subclass of object that is instantiated // |  | refactoring // |  |  | problem // |  |  |  | creating an object by specifying a class explicitly // |  |  | solution // |  |  |  | create objects indirectly // |  |  |  |  | also // |  |  |  |  |  | Abstract Factory // |  |  |  |  |  | Prototype // | APPLICABILITY // |  | a class // |  |  | can't anticipate the class of objects it must create // |  |  | wants its subclasses to specify the objects it creates // |  |  | delegates responsibility to one of several helper subclasses // |  |  |  | localize the knowledge of which helper subclass is the delegate // | STRUCTURE // |  | //                                                |        Creator        | //                                                |------------------------| //                                                |FactoryMethod()        | //                                                |AnOperation()          | //                                                | ...                    | //                                                | product=FactoryMethod()| //                |Product|                      | ...                    | //                    ^                                      ^ //                    |                                      | //            |ConcreteProduct|<- - - - - - - -|      ConcreteCreator      | //                                              |---------------------------| //                                              |FactoryMethod()            | //                                              | return new ConcreteProduct| // |  | #include <SRCPatternsPatterns.mqh> namespace FactoryMethod { // |  | // | PARTICIPANTS ------------------------------------------------------------------------------ // |  | PRODUCT // |  |  | interface of objects that the factory method creates // |  |  | interface Product   {   }; // |  |  | // |  | CONCRETE PRODUCT // |  |  | implements the Product interface // |  |  | class ConcreteProduct:public Product   { public:                     ConcreteProduct();   }; ConcreteProduct::ConcreteProduct(void)   {   Print("Hash: ",&this);   } // |  |  | // |  | CREATOR // |  |  | declares the factory method // |  |  |  | returns an object of type Product // |  |  |  | default implementation of the factory method // |  |  |  |  | returns a default ConcreteProduct object // |  |  | may call the factory method to create a Product object // |  |  | class Creator   { public:   virtual Product*  FactoryMethod()=0;   void              AnOperation();                     ~Creator(); protected:   Product*          product;   }; Creator::~Creator(void)   {   delete product;   } void Creator::AnOperation(void)   {   delete product;   Print("Creator operation: creating product with a virtual factory method.");   product=FactoryMethod();   } // |  |  | // |  | CONCRETE CREATOR // |  |  | overrides the factory method // |  |  | returns an instance of a ConcreteProduct // |  |  | class ConcreteCreator:public Creator   { public:   Product*          FactoryMethod();   }; Product* ConcreteCreator::FactoryMethod(void)   {   Print("Concrete creator factory method: returning new product");   return new ConcreteProduct;   } // |  |  | // |  | CLIENT // |  |  | class Client:public ClientExample   { public:   string            Output();   void              Run();   }; string Client::Output()   {   return __FUNCTION__;   } // |  |  // | COLLABORATIONS ---------------------------------------------------------------------------- // |  | Creator // |  |  | relies on its subclasses // |  |  |  | to define the factory method // |  |  |  |  | returns an instance of the appropriate ConcreteProduct // |  |  void Client::Run()   {   ConcreteCreator creator;   Product* product=creator.FactoryMethod();   creator.AnOperation(); //---   delete product;   } } // |  | // | OUTPUT ------------------------------------------------------------------------------------ // |  | Creational::FactoryMethod::Client::Output // |  | Concrete creator factory method: returning new product // |  | Hash: 138412032 // |  | Creator operation: creating product with a virtual factory method. // |  | Concrete creator factory method: returning new product // |  | Hash: 139460608 // |  | // | CONSEQUENCES ------------------------------------------------------------------------------ // |  | Code only deals with the Product interface // |  |  | can work with any user-defined ConcreteProduct classes // |  |  | but clients might have to subclass the Creator class // |  |  |  | to create a particular ConcreteProduct object // |  | Provides hooks for subclasses // |  |  | creating objects inside a class is // |  |  |  | more flexible than creating an object directly // |  |  | the factory method is // |  |  |  | not abstract // |  |  |  | provides a reasonable default implementation // |  | Connects parallel class hierarchies when // |  |  | class delegates some of its responsibilities to a separate class // |  |  | consider graphical figures that // |  |  |  | can be manipulated interactively // |  |  |  |  | manipulator object // |  |  |  |  |  | implements the interaction // |  |  |  |  |  | keeps track of any manipulation-specific state that's needed // |  |  |  |  | figure class // |  |  |  |  |  | provides a factory method // |  |  |  |  |  |  | lets clients create a corresponding manipulator // |  |  |  |  | figure subclasses // |  |  |  |  |  | override this method to return an // |  |  |  |  |  |  | instance of the manipulator subclass that's right for them // | IMPLEMENTATION ---------------------------------------------------------------------------- // |  | Creator // |  |  | abstract // |  |  | concrete // |  |  |  | default implementation for the factory method // |  |  |  | the class of objects // |  |  |  |  | parent instantiates // |  |  |  |  | can be changed // |  | Parameterized factory methods // |  |  | new identifiers for new kinds of products // |  |  | associate existing identifiers with different products // |  | Language-specific variants and issues // |  |  | factory methods in c++ // |  |  |  | always virtual functions // |  |  |  | often pure virtual // |  |  |  | use lazy initialization // |  |  |  |  | creator's constructor doesn't call factory methods // |  | Using templates to avoid subclassing // |  |  | template subclass of creator // |  |  |  | parameterized by the product class // |  | Naming conventions // |  |  | make use of factory methods clear //----------------------------------------------------------------------------------------------