享元模式
目录享元模式模式定义模式动机UML类图源码实现优点缺点
模式定义
享元模式(Flyweight),运用共享技术有效的支持大量细粒度的对象。
模式动机
如果一个应用使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用。当对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享内存对象取代很多组对象,此时可以考虑使用享元模式。UML类图
源码实现
piece.h#includestringenumColor{white,black};classPiece{public:Piece(Colorcolor);voidsetPoint(intx,inty);ColorGetColor()const;public:intm_X;intm_Y;private:Colorm_Color;};piece.cpp#includepiece.hPiece::Piece(Colorcolor):m_Color(color){}voidPiece::setPoint(intx,inty){m_X=x;m_Y=y;}ColorPiece::GetColor()const{returnm_Color;}checkerboard.h#includestring#includepiece.hclassCheckerBoard{public:CheckerBoard();voidDraw();voidrefresh();voidGetPiece(constPiecepiece);private:std::stringm_Checker;};checkerboard.cpp#includeiostream#includestring.h#includecheckerboard.hCheckerBoard::CheckerBoard(){for(intm=0;m20;++m){for(intn=0;n20;++n)m_Checker.append(o);m_Checker.append(\n);}}voidCheckerBoard::Draw(){std::coutm_Checker;}voidCheckerBoard::refresh(){system(cls);std::coutm_Checker;}voidCheckerBoard::GetPiece(constPiecepiece){intpos;pos=(piece.m_Y*21)+piece.m_X;if(piece.GetColor()==Color::white)m_Checker.replace(pos,1,-);elseif(piece.GetColor()==Color::black)m_Checker.replace(pos,1,+);}piecefactory.h#includemap#includepiece.hclassPieceFactory{public:PieceFactory();Piece*find(Colorcolor);private:std::mapColor,Piece*m_PiecesMap;};piecefactory.cpp#includememory#includepiecefactory.hPieceFactory::PieceFactory(){}Piece*PieceFactory::find(Colorcolor){autopiece=m_PiecesMap.find(color);if(piece!=m_PiecesMap.end()){returnpiece-second;}else{Piece*p=newPiece(color);m_PiecesMap[color]=p;returnp;}}main.cpp/*************************************
brief :享元模式*author :wzx*date :-07-16*project :FlyWeight*************************************/#includeiostream#includerandom#includetime.h#includethread#includeunistd.h#includecheckerboard.h#includepiecefactory.h#includepiece.husingnamespacestd;voidGeneratePoint(Piece*p){//随机数生成有点问题std::mtrnd(time(0));p-m_X=rnd()%20;p-m_Y=rnd()%20;}intmain(){CheckerBoardboard;board.Draw();PieceFactoryfactory;for(intn=0;n20;++n){Piece*p1=factory.find(Color::black);GeneratePoint(p1);sleep(1);Piece*p2=factory.find(Color::white);GeneratePoint(p2);board.GetPiece(*p2);board.GetPiece(*p1);board.refresh();}return0;}运行结果oooooooooooooooooooooooooooooo+ooooooooo-+ooooooooooooooooooooooooooooooooooooooooooooo-oooo+oo+ooooooooooooooooooooooooo+oooooooooooooooooooooo++oo+ooooooooooo注:随机数生成算法有点问题,这里忽略最终结果优点
模式的优点
享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本都是相同的,有时就能够受大幅度地减少需要实例化的类的数量。如果能把哪些参数移到类实例的外面,在方法调用的时候将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。缺点
模式的缺点
使用享元模式需要维护一个记录了系统已有的所有享元的列表,而这本身需要耗费资源。享元模式使得系统更加的复杂,为了使对象可以共享,需要将一些状态外部化,这是得程序的逻辑复杂化。因此,应当在有足够多的对象实例可供共享时才值得使用享元模式。