享元模式很常见,是一种减小内存的方式,大到三维场景中的一个房子,小到文字处理系统中的一个英文字母,都可以使用享元模式。
借鉴一下《大话设计模式》中的uml图吧
下面是代码:
// Flyweight.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <Windows.h> #include <vector> #include <string> using namespace std; // 享元模式(Flyweight)。运用共享技术有效地支持大量细粒度的对象。 // 假设场景 // 某个三维游戏场景,有一片森林,准备用一棵树,通过摆放位置不同, // 缩放,角度不同的三棵树摆出一整片森林。 // 时间关系,先不写析构部分了 class Obj { public: Obj(const string &str) : m_strName(str) { } virtual void PrintInfo() {;} protected: string m_strName; }; // 模型几何信息 class Mesh : public Obj { public: Mesh(const string &str) : Obj(str) { } void PrintInfo() { string str = "Mesh information of " + m_strName; printf(str.c_str()); } }; // 模型渲染信息 class RenderObject : public Obj { public: RenderObject(const string &str) : Obj(str) { } void PrintInfo() { string str = "Render information " + m_strName; printf(str.c_str()); } }; // 模型类 class Model : public Obj { public: Model(const string &strName) : Obj(strName) , m_pMesh(new Mesh( strName)) , m_pRO(new RenderObject(strName)) { } virtual void PrintInfo() { ; } protected: Mesh *m_pMesh; RenderObject *m_pRO; }; // 模型姿态信息,其实每个模型都有自己的姿态 // 现在假设只有模型树的姿态是需要自己设置的 class POSInfo { public: POSInfo(double centerX, double centerY, double centerZ, double yaw, double pitch, double roll, double xScale, double yScale, double zScale) : m_x(centerX) , m_y(centerY) , m_z(centerZ) { //..... } double m_x; double m_y; double m_z; }; // 模型树类 class TreeModel : public Model { public: TreeModel(const string &strName) : Model(strName) , m_pInfo(new POSInfo(0,0,0,0,0,0,1,1,1)) { } ~TreeModel() { //only need to delete pos info } void CreateNewInstacne(POSInfo *pInfo) { m_pInfo = pInfo; } void PrintInfo() { printf("\n.........\n"); m_pMesh->PrintInfo(); m_pRO->PrintInfo(); printf(m_strName.c_str()); printf(" : \ndetail information :\nx:%lf, y:%lf, z:%lf",m_pInfo->m_x, m_pInfo->m_y, m_pInfo->m_z); printf("\n.........\n"); } protected: string m_strName; POSInfo *m_pInfo; }; class TreeModelFactory { public: TreeModelFactory() { TreeModel *pTM1 = new TreeModel("大树"); TreeModel *pTM2 = new TreeModel("小树"); TreeModel *pTM3 = new TreeModel("小小树"); m_TreeModelVec.push_back(pTM1); m_TreeModelVec.push_back(pTM2); m_TreeModelVec.push_back(pTM3); } TreeModel* GetTreeInstance(int num) { if (num >= 0 && num <= 2) { return m_TreeModelVec[num]; } return NULL; } ~TreeModelFactory() { // ....... // delete tree // delete mesh // delete ro } private: vector<TreeModel*> m_TreeModelVec; }; int _tmain(int argc, _TCHAR* argv[]) { TreeModelFactory *pTreeFactory = new TreeModelFactory(); TreeModel* pT1 = pTreeFactory->GetTreeInstance(0); pT1->CreateNewInstacne(new POSInfo(1, 2,3,0,0,0,1,2,3)); pT1->PrintInfo(); TreeModel *pT2 = pTreeFactory->GetTreeInstance(2); pT2->CreateNewInstacne(new POSInfo(6, 2,3,7,0,0,1,2,3)); pT2->PrintInfo(); TreeModel *pT3 = pTreeFactory->GetTreeInstance(2); pT3->CreateNewInstacne(new POSInfo(10, 12,30,7,0,0,1,2,3)); pT3->PrintInfo(); // ... // ... // 这样森林中所有的树只有三种几何体和渲染体,比较节省内存 // // 当然,如果要给每一个不同的树一个序号或者要保存每一颗树的信息,可以加一个TreeInstance类 // TreeIns包含序号,位置指针和treeModel的指针即可 // 如果不需要保存这些信息,那么只需要保存PosInfo列表 // 需要的时候再进行组合(CreateNewInstacne),然后打印信息 return 0; }
输出结果
.........
Mesh information of 大树Render information 大树 :
detail information :
x:1.000000, y:2.000000, z:3.000000
.........
.........
Mesh information of 小小树Render information 小小树 :
detail information :
x:6.000000, y:2.000000, z:3.000000
.........
.........
Mesh information of 小小树Render information 小小树 :
detail information :
x:10.000000, y:12.000000, z:30.000000
.........
请按任意键继续. . .