1 2 3 4 5 6 7 8 9 10 11 12 …">

帐前卒专栏

Without software, we are nothing.

Design Pattern -- Flyweight

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;
}

Comments