반응형
Prototype
1.소스
#includeusing 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(); } } class LandSatImage: public Image { public: imageType returnType() { return LSAT; } void draw() { cout << "LandSatImage::draw " << _id << endl; } // When clone() is called, call the one-argument ctor 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 ctor 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; 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 }; int 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 for (i = 0; i < NUM_IMAGES; i++) images[i]->draw(); // Free the dynamic memory for (i = 0; i < NUM_IMAGES; i++) delete images[i]; }
결과
g++ -o prototype prototype.cpp hacker@HACKER:~/cpp$ hacker@HACKER:~/cpp$ hacker@HACKER:~/cpp$ ./prototype LandSatImage::draw 1 LandSatImage::draw 2 LandSatImage::draw 3 SpotImage::draw 1 LandSatImage::draw 4 SpotImage::draw 2 SpotImage::draw 3 LandSatImage::draw 5
반응형
'C++ > 0x01-design pattern' 카테고리의 다른 글
Chain of Responsibility (0) | 2016.07.18 |
---|---|
Factory Method (0) | 2016.07.18 |
builder pattern (0) | 2016.07.18 |
proxy pattern (0) | 2016.07.18 |
Flyweight pattern (0) | 2016.07.18 |