//---prototype-------------------------------------------------------- // creational design pattern // ---intent // create objects by copying a prototype // ---benefits------------------------------------------------------ // class of object that is instantiated may vary // ---refactoring problem // creating an object by specifying a class explicitly // ---solution // create objects indirectly // also abstract factory, factory method // ---applicability ------------------------------------------------ // classes to instantiate are specified at run-time // no duplication of factories/products class hierarchies // objects have one of a few combinations of state // install prototypes and clone them // don't instantiate the class with state manually // ---structure // prototype // | Client |--------------------->|Prototype| // |--------------------| |---------| // |Operation() | |Clone() | // | p=prototype.Clone()| ^ // | // +--------------+---------------+ // | | // | ConcretePrototype1 | | ConcretePrototype2 | // |--------------------| |--------------------| // |Clone() | |Clone() | // | return copy of self| | return copy of self| // #include <SRC\Patterns\Patterns.mqh> namespace Prototype { //---participants----------------------------------------------------- class Prototype //interface for cloning itself { public: int id; virtual Prototype* Clone()=0; Prototype(int); }; Prototype::Prototype(int i):id(i) {} //---participants----------------------------------------------------- class ConcretePrototype1:public Prototype //implements an operation for cloning itself { public: ConcretePrototype1(int); Prototype* Clone(); }; ConcretePrototype1::ConcretePrototype1(int i):Prototype(i) {} Prototype* ConcretePrototype1::Clone(void) { Print("Cloning Concrete Prototype 1 with id: ",id); return new ConcretePrototype1(id); } //---participants----------------------------------------------------- class ConcretePrototype2:public Prototype //implements an operation for cloning itself { public: ConcretePrototype2(int); Prototype* Clone(); }; ConcretePrototype2::ConcretePrototype2(int i):Prototype(i) {} Prototype* ConcretePrototype2::Clone(void) { Print("Cloning Concrete Prototype 2 with id: ",id); return new ConcretePrototype2(id); } //---participants----------------------------------------------------- class Client:public ClientExample //creates a new object by asking a prototype to clone itself { public: string Output(); void Run(); }; string Client::Output() {return __FUNCTION__;} //---collaborations--------------------------------------------------- // client asks a prototype to clone itself void Client::Run() { Prototype* prototype; Prototype* clone; prototype=new ConcretePrototype1(1); clone=prototype.Clone(); delete prototype; delete clone; //--- prototype=new ConcretePrototype2(2); clone=prototype.Clone(); delete prototype; delete clone; } } //---output----------------------------------------------------------- // Creational::Prototype::Client::Output // Cloning Concrete Prototype 1 with id: 1 // Cloning Concrete Prototype 2 with id: 2 //---consequences----------------------------------------------------- // ---hides the concrete product classes from the client // reduces the number of names clients know about // ---lets a client work with application-specific classes without modification // ---adding and removing products at run-time // register a prototypical instance with the client // more flexible than other creational patterns // ---specifying new objects by varying values // define new behavior through object composition // define new kinds of objects by // instantiating existing classes // registering the instances as prototypes of client objects // cloning a prototype is similar to instantiating a class // ---specifying new objects by varying structure // build objects from parts and subparts // as long as the composite circuit implements clone as a deep copy // circuits with different structures can be prototypes // ---reduced subclassing // clone a prototype // don't ask a factory method to make a new object // creator hierarchy not needed at all // ---configuring an application with classes dynamically // run-time // object is created automatically when it's loaded // object with a prototype manager is registered // objects of newly loaded classes are provided // weren't linked with the program originally //---implementation -------------------------------------------------- // ---prototype manager // client will ask the manager for a prototype before cloning it // prototype manager // associative store // returns the prototype matching a given key // clients at run-time can change, browse it // ---clone() // default copy constructor in c++ does a member-wise copy // pointers will be shared between the copy and the original // cloning prototypes with complex structures requires a deep copy // clone and original must be independent // save() // the object into a memory buffer // load() // duplicate by reconstructing the object from the buffer // ---initializing clones // initialize() // takes initialization parameters as arguments // sets the clone's internal state // beware of deep-copying clone operations // copies may have to be deleted before reinitialization // explicitly or in initialize() //---related patterns------------------------------------------------- // ---abstract factory // competes in some ways // can also be used together // store a set of prototypes from which to clone and return product objects // ---composite, decorator // often can benefit from prototype
Home
Creational
Design
MetaTrader 5 Libraries
Patterns
Prototype
MetaTrader 5 Libraries | Design patterns - Prototype (creational)
MetaTrader 5 Libraries | Design patterns - Prototype (creational)
Subscribe to:
Post Comments (Atom)