1 / 8

Creational Pattern: Prototype

Creational Pattern: Prototype. Chapter 3 – Page 37. While the Factory Method pattern lets a class defer instantiation to its subclasses, the Prototype pattern uses delegation to accomplish the same task.

rob
Download Presentation

Creational Pattern: Prototype

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Creational Pattern: Prototype Chapter 3 – Page 37 While the Factory Method pattern lets a class defer instantiation to its subclasses, the Prototype pattern uses delegation to accomplish the same task. Rather than undergo the built-in cost of generating new objects whenever they need to be created, a prototype of the desired object is “cloned” and modified as desired. The prototypes themselves are often created prior to run-time, with their cloned variations added at run-time.

  2. The Prototype Pattern Chapter 3 – Page 38 The Prototype declares an interface for cloning itself. Each ConcretePrototype implements an operation for cloning itself. The Client creates a new object by asking the Prototype to clone itself. Note that the Prototype pattern is unique among the Creational Design Patterns in that it doesn’t actually require a class; some pure object-oriented languages (e.g., Self, Omega) do away with classes entirely and rely exclusively on prototypes to create new objects.

  3. Non-Software Example Chapter 3 – Page 39 Assume that an e-commerce application gathers product information via complicated queries against a legacy database, which is updated at a known set of predefined intervals. The application could instantiate the product information (via cloning) at these predefined intervals and keep it in a cache. When a user requests information about a certain product, it is retrieved from the cache and cloned. When the legacy database is updated, the contents of the cache are discarded and reloaded with new objects.

  4. Prototype Example: Images Chapter 3 – Page 40 The client is using two types of satellite images, the American LandSat images and the European SPOT images, implemented as subclasses of an Image prototype. Whenever the client needs a clone of a particular type, the clone() operator is called on the correct derived class.

  5. C++ Code for Image Prototype Chapter 3 – Page 41 #include <iostream> using namespace std; enumimageType { LSAT, SPOT }; class Image { public: virtual void draw() = 0; static Image *findAndClone(imageType); protected: virtualimageTypereturnType() = 0; virtual Image *clone() = 0; // As each subclass of Image is declared, it registers its prototype static voidaddPrototype(Image *image) { prototypes[nextSlot++] = image; } private: // addPrototype() saves each registered prototype here static Image *prototypes[10]; static intnextSlot; }; Image *Image::prototypes[]; int Image::nextSlot; // Client calls this public static member function // when it needs an instance of an Image subclass Image *Image::findAndClone(imageType type) { for (inti = 0; i < nextSlot; i++) if (prototypes[i]->returnType() == type) return prototypes[i]->clone(); return NULL; }

  6. Chapter 3 – Page 42 classLandSatImage: public Image { public: imageTypereturnType() { return LSAT; } void draw() { cout << "LandSatImage::draw " << id << endl; } // When clone() is called, call the one-argument // constructor with a dummy arg Image *clone() { return new LandSatImage(1); } protected: // This is only called from clone() LandSatImage(int dummy) { id = count++; } private: // Mechanism for initializing an Image subclass - this causes the default // constructor to be called, which registers the subclass's prototype staticLandSatImagelandSatImage; // This is only called when the private static data member is inited LandSatImage() { addPrototype(this); } // Nominal "state" per instance mechanism int id; static intcount; }; // Register the subclass's prototype LandSatImageLandSatImage::landSatImage; // Initialize the "state" per instance mechanism intLandSatImage::count = 1;

  7. classSpotImage: public Image { public: imageTypereturnType() { return SPOT; } void draw() { cout << "SpotImage::draw " << id << endl; } Image *clone() { return new SpotImage(1); } protected: SpotImage(int dummy) { id = count++; } private: SpotImage() { addPrototype(this); } staticSpotImagespotImage; int id; static intcount; }; SpotImageSpotImage::spotImage; intSpotImage::count = 1; // Simulated stream of creation requests const intNUM_IMAGES = 8; imageType input[NUM_IMAGES] = { LSAT, LSAT, LSAT, SPOT, LSAT, SPOT, SPOT, LSAT }; void main() { Image *images[NUM_IMAGES]; inti; // Given an image type, find the right prototype, and return a clone for (i = 0; i < NUM_IMAGES; i++) images[i] = Image::findAndClone(input[i]); // Demonstrate that correct image objects have been cloned for (i = 0; i < NUM_IMAGES; i++) images[i]->draw(); // Free the dynamic memory for (i = 0; i < NUM_IMAGES; i++) delete images[i]; } Chapter 3 – Page 43

  8. Prototype Design Advantages Chapter 3 – Page 44 • The Prototype pattern hides the complexities of making new instances from the client, which can be very helpful when there is a complex class hierarchy and new objects of many different types need to be created. • If the objects are complicated enough, copying an object can be more efficient that creating a new one. • In addition to the inheritance-vs.-delegation difference, the Prototype pattern differs from the Factory Method pattern in that Prototype doesn’t require subclasses but does require initialization, while Factory Method doesn’t require initialization but does require subclasses.

More Related