Presentation is loading. Please wait.

Presentation is loading. Please wait.

Creational Pattern: Prototype

Similar presentations


Presentation on theme: "Creational Pattern: Prototype"— 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; enum imageType { LSAT, SPOT }; class Image { public: virtual void draw() = 0; static Image *findAndClone(imageType); protected: virtual imageType returnType() = 0; virtual Image *clone() = 0; // As each subclass of Image is declared, it registers its prototype static void addPrototype(Image *image) { prototypes[nextSlot++] = image; } private: // addPrototype() saves each registered prototype here static Image *prototypes[10]; static int nextSlot; }; 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 (int i = 0; i < nextSlot; i++) if (prototypes[i]->returnType() == type) return prototypes[i]->clone(); return NULL; }

6 Chapter 3 – Page 42 class LandSatImage: public Image { public:
imageType returnType() { 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 static LandSatImage landSatImage; // This is only called when the private static data member is inited LandSatImage() { addPrototype(this); } // Nominal "state" per instance mechanism int id; static int count; }; // Register the subclass's prototype LandSatImage LandSatImage::landSatImage; // Initialize the "state" per instance mechanism int LandSatImage::count = 1;

7 Chapter 3 – Page 43 class SpotImage: public Image { public:
imageType returnType() { 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); } static SpotImage spotImage; int id; static int count; }; SpotImage SpotImage::spotImage; int SpotImage::count = 1; // Simulated stream of creation requests const int NUM_IMAGES = 8; imageType input[NUM_IMAGES] = { LSAT, LSAT, LSAT, SPOT, LSAT, SPOT, SPOT, LSAT }; void main() Image *images[NUM_IMAGES]; int i; // 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 images[i]->draw(); // Free the dynamic memory 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.


Download ppt "Creational Pattern: Prototype"

Similar presentations


Ads by Google