// Purpose. Flyweight design pattern lab // // Discussion. Let's say 20 bytes per gadget is unacceptable overhead. We // want to "lighten up" the Gadget hierarchy, and, share a small number of // "real" instances across a larger number of "virtual" instances. // // Assignment. // o Replace the current main() with the one commented-out at the end // o Gadget's x_, y_, and w_ are not shareable. Remove them from Gadget's // private state, and, modify draw() to accept x, y, and w. // o Add a Factory class that supports the expectations in the new main() // o Factory could use a static array of 2 Gadget ptrs as its "cache" or // "pool" data structure (don't forget to init this static array) // o getFlyweight() will check this static array to see if the requested // flyweight exists (if it doesn't, it will create it), and then return it // o Notice how the "client" code in main() got more complicated. The client // is responsible for knowing (or computing) the new "extrinsic" state and // passing that state to the flyweight objects. #include // Microsoft Visual C++ code #include #include HANDLE console_ = GetStdHandle(STD_OUTPUT_HANDLE); void gotoxy( int x, int y ) { COORD coord; coord.X = x-1; coord.Y = y-1; SetConsoleCursorPosition( console_, coord ); } class Gadget { public: Gadget( int col, int row, int width, char ch ) { x_ = col; y_ = row; w_ = width; ch_ = ch; } virtual void draw() { int i; gotoxy( x_, y_ ); for (i=0; i < w_; i++) cout << ch_; cout << endl; gotoxy( x_, y_+1 ); cout << ch_; for (i=0; i < w_-2; i++) cout << ' '; cout << ch_ << endl; gotoxy( x_, y_+2 ); for (i=0; i < w_; i++) cout << ch_; cout << endl; } private: long x_, y_, w_; char ch_; }; class Label : public Gadget { public: Label( int col, int row, int width ) : Gadget(col,row,width,'@') { } }; class Edit : public Gadget { public: Edit( int col, int row, int width ) : Gadget(col,row,width,'#') { } }; void main( void ) { Gadget* list[] = { new Label( 10, 1, 5 ), new Label( 10, 4, 7 ), new Label( 10, 7, 9 ), new Edit( 16, 1, 9 ), new Edit( 18, 4, 7 ), new Edit( 20, 7, 5 ) }; for (int i=0; i < 6; i++) list[i]->draw(); for (i=0; i < 6; i++) delete list[i]; cout << "\nsizeof Gadget is " << sizeof(Gadget) << endl; cout << "sizeof Label is " << sizeof(Label) << endl; } // @@@@@ ######### // @ @ # # // @@@@@ ######### // @@@@@@@ ####### // @ @ # # // @@@@@@@ ####### // @@@@@@@@@ ##### // @ @ # # // @@@@@@@@@ ##### // // sizeof Gadget is 20 // sizeof Label is 20 #if 0 void main( void ) { Gadget* list[6]; list[0] = Factory::getFlyweight( "label" ); list[1] = Factory::getFlyweight( "label" ); list[2] = Factory::getFlyweight( "label" ); list[3] = Factory::getFlyweight( "edit" ); list[4] = Factory::getFlyweight( "edit" ); list[5] = Factory::getFlyweight( "edit" ); for (int i=0; i < 3; i++) list[i]->draw( 10, i*3+1, i*2+5 ); for (i=3; i < 6; i++) list[i]->draw( (i-3)*2+16, (i-3)*3+1, 9-(i-3)*2 ); cout << "\nsizeof Gadget is " << sizeof(Gadget) << endl; cout << "sizeof Label is " << sizeof(Label) << endl; } #endif