设计模式之享元模式

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

#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了,大家不妨试试,好了,本篇博文到此结束,接下来我们会继续学习设计模式之桥接模式。

如果需要,请注明转载,多谢

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值