1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
| // flyweight.cpp : Defines the entry point for the console application. // author: chillyc // email: chillycreator @t gmail.com
#include<iostream> #include<map> namespace pattern{
/// this is flyweight pattern /// In text processing, there will be thousands of hundreds of characters. /// If we construct too many this class instance, and /// imaging this class will have many member variables, will the system be efficient? /// So we just record the characters state, and not care about other part of character. /// we shall save a lot of main memories, shall we? /// If there are many characters, but they are only in differnt place, we can reuse characters. /// So there are Fly_Manager to record the shared objects or states. /// All objects should be derived from Metadata class. /// Graphdata is no-shared metadata. And Character is shared metadata. /// In main function, you will see the difference between two of them.
#ifndef STATE_H #define STATE_H class State{ private: int font_num; int style;
public: void Set_Font_Num(int num){font_num = num;} void Set_Style(int style){this->style = style;} int Get_Font_Num(){return font_num;} int Get_Style(){return style;} State(){} State(int num,int style){ font_num = num; this->style = style; } State(const State& state){ this->font_num = state.font_num; this->style = state.style; } State* operator = (const State& state){ this->font_num = state.font_num; this->style = state.style; return this; } };
#endif
#ifndef METADATA_H #define METADATA_H class Metadata{ public: virtual void show()=0; }; #endif
#ifndef character_H #define character_H // share the basic information // here you should image character has a huge infomation, // and state is only a small part of this class class character: public Metadata{ private: State state; public: // set state to default state character():Metadata(),state(1,1){} ~character(){} void Set_State(State& state); virtual void show();
}; void character::Set_State(pattern::State& state){ this->state = state; }
void character::show(){ std::cout << "write a character font is "<< state.Get_Font_Num()<< " style is " << state.Get_Style()<<std::endl; } #endif
#ifndef GRAPHDATA_H #define GRAPHDATA_H // not share class Graphdata: public Metadata{ private: State state; public: Graphdata(State & state):Metadata(),state(state){} // font num is not used Graphdata(int style):Metadata(),state(-1,style){} ~Graphdata(){}; virtual void show(); };
#endif void Graphdata::show(){ // only use its own state std::cout<< "print a graph! style is "<<state.Get_Style()<<std::endl; }
#ifndef FLYMANAGER_H #define FLYMANAGER_H class Fly_Manager{ public: // suggest you should make it as private or protected std::map<int,State> characters; Fly_Manager(){} void Set_I(int i, State& state); State& Get_I(int i); ~Fly_Manager(){}
}; #endif void Fly_Manager::Set_I(int i, State& state){ characters[i] = state; } State& Fly_Manager::Get_I(int i){ return characters[i]; }
} int main() { pattern::Fly_Manager fm; pattern::character c; pattern::State s1(1,2); pattern::State s2(2,3); pattern::State s3(3,4); fm.Set_I(0,s1); fm.Set_I(1,s2); fm.Set_I(2,s3); pattern::Graphdata gd1(2); pattern::Graphdata gd2(9); for(int i = 0; i < 3; i++){ c.Set_State(fm.Get_I(i)); c.show(); } gd1.show(); gd2.show(); return 0; }
|