在上一篇博文中,我们学习了代理模式,代理模式最大的特点:将实际的操作对象进行封装成为一个代理,对于上层所有的用户请求都是由代理对象代之完成,这种模式的优点就是使得程序的封装性很好,能够提高模块之间的内聚度,今天我们在此学习下面一个设计模式——享元模式,从名字中我们可能就已经只知道这种模式的特点:就是共享,一般之中模式是使用在一些能够共享对象的地方,首先我们来看看享元模式的定义吧,享元模式:运用共享的技术有效地支持大量细粒度的对象。一般的享元可分为具体享元,抽象享元以及享元工厂,好了,说了这么多,还是来看代码吧,首先从一个比较普通的例子入手吧,代码如下:
#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了,大家不妨试试,好了,本篇博文到此结束,接下来我们会继续学习设计模式之桥接模式。
如果需要,请注明转载,多谢