在上一篇博文中,我们学习了代理模式,代理模式最大的特点:将实际的操作对象进行封装成为一个代理,对于上层所有的用户请求都是由代理对象代之完成,这种模式的优点就是使得程序的封装性很好,能够提高模块之间的内聚度,今天我们在此学习下面一个设计模式——享元模式,从名字中我们可能就已经只知道这种模式的特点:就是共享,一般之中模式是使用在一些能够共享对象的地方,首先我们来看看享元模式的定义吧,享元模式:运用共享的技术有效地支持大量细粒度的对象。一般的享元可分为具体享元,抽象享元以及享元工厂,好了,说了这么多,还是来看代码吧,首先从一个比较普通的例子入手吧,代码如下:
#ifndef __SHARE__H #define __SHARE__H #include<stdio.h> #include<map> #include<boost/shared_ptr.hpp> using namespace std; using namespace boost; struct Position { Position() { posX = 0; posY = 0; } int posX; int posY; }; class Character { public: Character(string symbol=string(),int size = 0,string font = string(),Position position = Position()):symbo { } virtual ~Character(){} void display() { printf("Symbol:%s size:%d font=%s posX=%d posY=%d\n",symbol.c_str(),size,font.c_str(),position.posX,po } void setPoistion(Position& pos) { position.posX = pos.posX; position.posY = pos.posY; } private: string symbol; int size; string font; Position position; }; class CharacterA : public Character { public: CharacterA(string symbol = string(),int size= 0,string font = string(),Position position = Position()):Cha ~CharacterA(){} }; class CharacterB : public Character { public: CharacterB(string symbol = string(),int size = 0,string font = string(),Position position = Position()):Ch ~CharacterB(){} }; class CharacterC : public Character { public: CharacterC(string symbol = string(),int size = 0,string font = string(),Position position = Position()):Ch ~CharacterC(){} }; class CharacterFactory { public: CharacterFactory() { diectoryMap.insert(std::make_pair(‘A‘,shared_ptr<CharacterA>(new CharacterA("A",10,"New Times")))); diectoryMap.insert(std::make_pair(‘B‘,shared_ptr<CharacterB>(new CharacterB("B",20,"Calls")))); diectoryMap.insert(std::make_pair(‘C‘,shared_ptr<CharacterC>(new CharacterC("C",30,"Itian")))); } ~CharacterFactory(){} void print(const char* charArray) { const char* pointer = charArray; while(*pointer != ‘\0‘) { Position position; position.posY = 0; position.posX = pointer - charArray; diectoryMap[*pointer]->setPoistion(position); diectoryMap[*pointer++]->display(); } } private: std::map<char,shared_ptr<Character> > diectoryMap; typedef std::map<char,shared_ptr<Character> >::iterator diectoryMap_iter; }; #endif #include "Share.h" int main(int argc,char* argv[]) { const char* buffer = "ABCACCBBCCAAA"; shared_ptr<CharacterFactory> charactorFactory(new CharacterFactory()); charactorFactory->print(buffer); return 0; }测试结果:
Symbol:A size:10 font=New Times posX=0 posY=0
Symbol:B size:20 font=Calls posX=1 posY=0
Symbol:C size:30 font=Itian posX=2 posY=0
Symbol:A size:10 font=New Times posX=3 posY=0
Symbol:C size:30 font=Itian posX=4 posY=0
Symbol:C size:30 font=Itian posX=5 posY=0
Symbol:B size:20 font=Calls posX=6 posY=0
Symbol:B size:20 font=Calls posX=7 posY=0
Symbol:C size:30 font=Itian posX=8 posY=0
Symbol:C size:30 font=Itian posX=9 posY=0
Symbol:A size:10 font=New Times posX=10 posY=0
Symbol:A size:10 font=New Times posX=11 posY=0
Symbol:A size:10 font=New Times posX=12 posY=0
上面的这个代码主要是用于说明享元模式,没有啥实用性,下面我们就来用享元模式写点有实用性的代码吧,就一个简单的画图程序吧,在这个画图程序里面,我们可以指定图形的颜色,图形的形状以及图形的大小和位置,代码如下
#ifndef __DRAW__H #define __DRAW__H #include <stdio.h> #include <map> #include <boost/smart_ptr.hpp> using namespace std; using namespace boost; enum Color { RED = 1, GREEN, BLUE, YELLOW, GRADE }; enum shape { CIRCLE = 1, RECTANGLE }; struct Position { Position() { posX = 0; posY = 0; } int posX; int posY; }; class Shape { public: virtual void draw(){} virtual void setRadis(int){} virtual void setColor(Color){} virtual void setPosition(Position&){} virtual void setLPosition(Position&){} virtual void setRPosition(Position&){} }; class Circle : public Shape { public: Circle(Color color = RED):color(color) { sh = CIRCLE; radis = 0; } ~Circle(){} void setPosition(Position& pos) { position.posX = pos.posX; position.posY = pos.posY; } void setRadis(int radis) { this->radis = radis; } void setColor(Color co) { color = co; } void draw() { printf("draw a circle,radis:%d,color:%d,posX:%d,posY:%d\n",radis,color,position.posX,position.posY); } private: Color color; shape sh; Position position; int radis; }; class Rectangle : public Shape { public: Rectangle(Color color = RED):color(color){ sh = RECTANGLE; } ~Rectangle(){} void setLPosition(Position& pos) { lpos.posX = pos.posX; lpos.posY = pos.posY; } void setRPosition(Position& pos) { rpos.posX = pos.posX; rpos.posY = pos.posY; } void setColor(Color col) { color = col; } void draw() { printf("draw a rectangle,lposx:%d,lposy:%d,rposx:%d,rposy:%d\n",lpos.posX,lpos.posY,rpos.posX,rpos.pos } private: Color color; shape sh; Position lpos; Position rpos; }; class DrawFactory { public: DrawFactory() { dirctoryShapeMap.clear(); } ~DrawFactory(){} int size() const { return dirctoryShapeMap.size(); } shared_ptr<Shape> createShape(shape sh) { switch(sh) { case CIRCLE: { shared_ptr<Shape> circle(new Circle()); dirctoryShapeMap.insert(std::make_pair(sh,circle)); return circle; } case RECTANGLE: { shared_ptr<Shape> rectangle(new Rectangle()); dirctoryShapeMap.insert(std::make_pair(sh,rectangle)); return rectangle; } } } shared_ptr<Shape> getShape(shape sh) { dirctoryShapeMap_iter iter = dirctoryShapeMap.find(sh); if(iter != dirctoryShapeMap.end()) return iter->second; return createShape(sh); } private: std::map<shape,shared_ptr<Shape> > dirctoryShapeMap; typedef std::map<shape,shared_ptr<Shape> >::iterator dirctoryShapeMap_iter; }; #endif #include "Draw.h" int main(int argc,char* argv[]) { DrawFactory drawFactory; Position position; position.posX = 4; position.posY = 7; drawFactory.getShape(CIRCLE)->setRadis(10); drawFactory.getShape(CIRCLE)->setPosition(position); drawFactory.getShape(CIRCLE)->setColor(GREEN); drawFactory.getShape(CIRCLE)->draw(); position.posX = 10; position.posY = 20; drawFactory.getShape(RECTANGLE)->setLPosition(position); position.posX = 20; position.posY = 30; drawFactory.getShape(RECTANGLE)->setRPosition(position); drawFactory.getShape(RECTANGLE)->setColor(YELLOW); drawFactory.getShape(RECTANGLE)->draw(); printf("drawFactory size:%d\n",drawFactory.size()); drawFactory.getShape(CIRCLE)->setRadis(30); drawFactory.getShape(CIRCLE)->draw(); position.posX = 40; position.posY = 60; drawFactory.getShape(RECTANGLE)->setLPosition(position); position.posX = 70; position.posY = 90; drawFactory.getShape(RECTANGLE)->setRPosition(position); drawFactory.getShape(RECTANGLE)->draw(); printf("drawFactory size:%d\n",drawFactory.size()); position.posX = 60; position.posY = 90; drawFactory.getShape(CIRCLE)->setRadis(50); drawFactory.getShape(CIRCLE)->draw(); position.posX = 100; position.posY = 120; drawFactory.getShape(RECTANGLE)->setLPosition(position); position.posX = 140; position.posY = 160; drawFactory.getShape(RECTANGLE)->setRPosition(position); drawFactory.getShape(RECTANGLE)->draw(); printf("drawFactory size:%d\n",drawFactory.size()); return 0; }
测试结果:
draw a circle,radis:10,color:2,posX:4,posY:7
draw a rectangle,lposx:10,lposy:20,rposx:20,rposy:30
drawFactory size:2
draw a circle,radis:30,color:2,posX:4,posY:7
draw a rectangle,lposx:40,lposy:60,rposx:70,rposy:90
drawFactory size:2
draw a circle,radis:50,color:2,posX:4,posY:7
draw a rectangle,lposx:100,lposy:120,rposx:140,rposy:160
drawFactory size:2
总结
本篇博文简要地分析了下享元模式,其实享元模式很简单,其核心思想就是共享对象,本文实现了两个简单的案例,其实这两个简单的案例都可以进一步扩展的,例如第二个案例只要在VS下使用MFC的话,完全可以实现成一个简单的画图板程序,只需要将我们的draw函数进行改写一下就OK了,大家不妨试试,好了,本篇博文到此结束,接下来我们会继续学习设计模式之桥接模式。
如果需要,请注明转载,多谢
原文:http://blog.csdn.net/zmyer/article/details/21192225