设计模式简单代码之Flyweight模式(二)
作者:qmroom
来源:http://blog.csdn.net/qmroom
在上篇文章“设计模式简单代码之Flyweight模式”中,我们发现以下两个问题:
- 随着使用Flyweight模式的增多,发现需要增加大量的代码,使用不是很方便;
- 第二个问题也是最重要的问题,仔细研读代码,发现代码并没有释放字符串内存空间,大量使用会造成内存严重丢失。
解决问题一我们可以使用模板类解决;解决问题二我们需要为每个Flyweight增加一个容器类,并增加析构函数,代码如下:
- /*
- 作者:qmroom
- */
- // Flyweight.cpp
- #include <iostream>
- #include <map>
- #include <string>
- #include <process.h>
- using namespace std;
- typedef char CHAR;
- typedef CHAR *LPSTR;
- typedef const CHAR *LPCSTR;
- class Book
- {
- public:
- string GetPublish() {return *m_publishCompany;}
- string GetWriter() {return *m_writer;}
- int GetBookID() {return m_bookID;}
- int GetPrice() {return m_price;}
- string GetName() {return *m_name;}
- void SetPublish(string *s) {m_publishCompany = s;}
- void SetWriter(string *s) {m_writer = s;}
- void SetBookID(int id) {m_bookID = id;}
- void SetPrice(int price) {m_price = price;}
- void SetName(string *s) {m_name = s;}
- private:
- string *m_publishCompany; // 出版社
- string *m_writer; // 作者
- int m_bookID; // 书籍编号
- int m_price; // 价钱
- string *m_name; // 书名
- };
- //对象
- template<typename T_Value = string>
- class FlyweightItem
- {
- public:
- FlyweightItem(T_Value &s)
- {
- m_value = new T_Value(s);
- }
- virtual ~FlyweightItem()
- {
- delete(m_value);
- }
- inline T_Value *GetValue()
- {
- return m_value;
- }
- private:
- T_Value *m_value;
- };
- //对象容器
- template<typename T_Index=string, typename T_Value=string>
- class FlyweightStdMap : public map<T_Index, FlyweightItem<T_Value>*>
- {
- public:
- virtual ~FlyweightStdMap()
- {
- iterator itr;
- for (itr = this->begin(); itr != this->end(); itr++)
- {
- // second就是指 map<T_Index, FlyweightItem<T_Value>*>的 FlyweightItem<T_Value>*
- delete (*itr).second; //释放内存
- }
- }
- };
- //对象工厂
- template<typename T_Index=string, typename T_Value=string>
- class FlyweightItemStdFactory
- {
- public:
- typedef FlyweightItem<T_Value> item;
- typedef FlyweightStdMap<T_Index, T_Value> std_map;
- public:
- virtual item* GetItem(T_Index key)
- {
- item *p;
- FlyweightStdMap<T_Index, T_Value>::iterator it;
- it = mapPublish.find(key);
- //如果存在这个对象
- if(it != mapPublish.end() )
- {
- // second就是指 map<T_Index, FlyweightItem<T_Value>*>的 FlyweightItem<T_Value>*
- p = (*it).second;
- cout << "已经有这个对象: /"" << *(p->GetValue()) << "/" 你节省了" << strlen((*(p->GetValue())).c_str()) << "字节的空间" << endl;
- }
- else
- {
- // 插入这个item
- p = new item(key);
- mapPublish[key] = p;
- }
- return p;
- }
- inline T_Value *GetValue(T_Index key)
- {
- return GetItem(key)->GetValue();
- }
- private:
- std_map mapPublish;
- };
- typedef FlyweightItemStdFactory<> FlyweightFactory;
- void ShowBookInfo(Book book)
- {
- cout << "书名:" << book.GetName() << endl;
- cout << "编号:" << book.GetBookID() << endl;
- cout << "价钱:" << book.GetPrice() << endl;
- cout << "出版:" << book.GetPublish() << endl;
- cout << "作者:" << book.GetWriter() << endl;
- cout << endl;
- }
- void main()
- {
- FlyweightFactory pff; //出版社工厂
- FlyweightFactory wff; //作者工厂
- FlyweightFactory nff; //书名工厂
- Book book1, book2, book3;
- book1.SetPublish( pff.GetValue("机械工业出版社"));
- book1.SetWriter( wff.GetValue("qmroom"));
- book1.SetBookID(0000);
- book1.SetPrice(20);
- book1.SetName(nff.GetValue("<<C++好野>>"));
- ShowBookInfo(book1);
- book2.SetPublish( pff.GetValue("人民邮电出版社"));
- book2.SetWriter( wff.GetValue("qmroom"));
- book2.SetBookID(0001);
- book2.SetPrice(30);
- book2.SetName(nff.GetValue("<<C++是好劲>>"));
- ShowBookInfo(book2);
- book3.SetPublish( pff.GetValue("机械工业出版社"));
- book3.SetWriter( wff.GetValue("cqm"));
- book3.SetBookID(0002);
- book3.SetPrice(50);
- book3.SetName(nff.GetValue("<<C++无得顶,我是铁头功...>>"));
- ShowBookInfo(book3);
- system("pause");
- }
好了,至此可以看出,利用上面的代码已经可以很好的工作。但最好还是动手把代码拷贝到VC 里,编译运行一下,在释放内存的地方加上断点,便于深刻理解Flyweight模式。