设计模式--享元模式Flyweight(结构型)
一、享元模式
在一个系统中如果有多个相同的对象,这些对象有部分状态是可以共享的,我们运用共享技术就能有效地支持大量细粒度的对象。
二、例子
举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子。现在要实现一个围棋程序,该怎么办呢?首先要考虑的是棋子棋盘的实现,可以定义一个棋子的类,成员变量包括棋子的颜色、形状、位置等信息,另外再定义一个棋盘的类,成员变量中有个容器,用于存放棋子的对象。
(1)未采用享元模式的实现
//棋子颜色
enum PieceColor {BLACK, WHITE};
//棋子位置
struct PiecePos
{
int x;
int y;
PiecePos(int a, int b): x(a), y(b) {}
};
//棋子定义
class Piece
{
protected:
PieceColor m_color; //颜色
PiecePos m_pos; //位置
public:
Piece(PieceColor color, PiecePos pos): m_color(color), m_pos(pos) {}
~Piece() {}
virtual void Draw() {}
};
class BlackPiece: public Piece
{
public:
BlackPiece(PieceColor color, PiecePos pos): Piece(color, pos) {}
~BlackPiece() {}
void Draw() { cout<<"绘制一颗黑棋"<<endl;}
};
class WhitePiece: public Piece
{
public:
WhitePiece(PieceColor color, PiecePos pos): Piece(color, pos) {}
~WhitePiece() {}
void Draw() { cout<<"绘制一颗白棋"<<endl;}
}; class PieceBoard
{
private:
vector<Piece*> m_vecPiece; //棋盘上已有的棋子
string m_blackName; //黑方名称
string m_whiteName; //白方名称
public:
PieceBoard(string black, string white): m_blackName(black), m_whiteName(white){}
~PieceBoard() { Clear(); }
void SetPiece(PieceColor color, PiecePos pos) //一步棋,在棋盘上放一颗棋子
{
Piece * piece = NULL;
if(color == BLACK) //黑方下的
{
piece = new BlackPiece(color, pos); //获取一颗黑棋
cout<<m_blackName<<"在位置("<<pos.x<<','<<pos.y<<")";
piece->Draw(); //在棋盘上绘制出棋子
}
else
{
piece = new WhitePiece(color, pos);
cout<<m_whiteName<<"在位置("<<pos.x<<','<<pos.y<<")";
piece->Draw();
}
m_vecPiece.push_back(piece); //加入容器中
}
void Clear() //释放内存
{
int size = m_vecPiece.size();
for(int i = ; i < size; i++)
delete m_vecPiece[i];
}
}; int main()
{
PieceBoard pieceBoard("A","B");
pieceBoard.SetPiece(BLACK, PiecePos(, ));
pieceBoard.SetPiece(WHITE, PiecePos(, ));
pieceBoard.SetPiece(BLACK, PiecePos(, ));
pieceBoard.SetPiece(WHITE, PiecePos(, ));
}
(2)采用享元模式
在围棋中,棋子就是大量细粒度的对象。其属性有内在的,比如颜色、形状等,也有外在的,比如在棋盘上的位置。内在的属性是可以共享的,区分在于外在属性。因此,可以这样设计,只需定义两个棋子的对象,一颗黑棋和一颗白棋,这两个对象含棋子的内在属性;棋子的外在属性,即在棋盘上的位置可以提取出来,存放在单独的容器中。相比之前的方案,现在容器中仅仅存放了位置属性,而原来则是棋子对象。显然,现在的方案大大减少了对于空间的需求。
//棋子颜色
enum PieceColor {BLACK, WHITE};
//棋子位置
struct PiecePos
{
int x;
int y;
PiecePos(int a, int b): x(a), y(b) {}
};
//棋子定义
class Piece
{
protected:
PieceColor m_color; //颜色
public:
Piece(PieceColor color): m_color(color) {}
~Piece() {}
virtual void Draw() {}
};
class BlackPiece: public Piece
{
public:
BlackPiece(PieceColor color): Piece(color) {}
~BlackPiece() {}
void Draw() { cout<<"绘制一颗黑棋\n"; }
};
class WhitePiece: public Piece
{
public:
WhitePiece(PieceColor color): Piece(color) {}
~WhitePiece() {}
void Draw() { cout<<"绘制一颗白棋\n";}
}; class PieceBoard
{
private:
vector<PiecePos> m_vecPos; //存放棋子的位置
Piece *m_blackPiece; //黑棋棋子
Piece *m_whitePiece; //白棋棋子
string m_blackName;
string m_whiteName;
public:
PieceBoard(string black, string white): m_blackName(black), m_whiteName(white)
{
m_blackPiece = NULL;
m_whitePiece = NULL;
}
~PieceBoard() { delete m_blackPiece; delete m_whitePiece;}
void SetPiece(PieceColor color, PiecePos pos)
{
if(color == BLACK)
{
if(m_blackPiece == NULL) //只有一颗黑棋
m_blackPiece = new BlackPiece(color);
cout<<m_blackName<<"在位置("<<pos.x<<','<<pos.y<<")";
m_blackPiece->Draw();
}
else
{
if(m_whitePiece == NULL)
m_whitePiece = new WhitePiece(color);
cout<<m_whiteName<<"在位置("<<pos.x<<','<<pos.y<<")";
m_whitePiece->Draw();
}
m_vecPos.push_back(pos);
}
};
三、UML图,以围棋为例。棋盘中含两个共享的对象,黑棋子和白棋子,所有棋子的外在属性都存放在单独的容器中。

参考:
http://blog.csdn.net/wuzhekai1985/article/details/6670298
设计模式--享元模式Flyweight(结构型)的更多相关文章
- 享元模式 FlyWeight 结构型 设计模式(十五)
享元模式(FlyWeight) “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...
- 设计模式11: Flyweight 享元模式(结构型模式)
Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...
- Java设计模式15:常用设计模式之享元模式(结构型模式)
1. Java之享元模式(Flyweight Pattern) (1)概述: 享元模式是对象池的一种实现,英文名为"Flyweight",代表轻量级的意思.享元模式用来 ...
- 设计模式-享元模式(FlyWeight)
一.概念 享元模式是对象的结构模式,它以共享的方式高效的支持大量的细粒度对象,减少对象的数量,并达到节约内存的目的. 享元对象能够做到共享的关键,主要是区分了内部状态和外部状态,内部状态是对象是在建立 ...
- 大话设计模式--享元模式 Flyweight -- C++实现实例
1. 享元模式: 运用共享技术有效地支持大量细粒度的对象. 享元模式可以避免大量非常相似类的开销,在程序设计中,有时需要生成大量颗粒度的类实例来表示数据,如果能发现这些实例除了几个参数外基本都是相同的 ...
- 面向对象设计模式之Flyweight享元模式(结构型)
动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...
- 设计模式 笔记 享元模式 Flyweight
//---------------------------15/04/20---------------------------- //Flyweight 享元模式------对象结构型模式 /* 1 ...
- 设计模式(十)享元模式Flyweight(结构型)
设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...
- 深入浅出设计模式——享元模式(Flyweight Pattern)
模式动机 面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题.享元模式正是为解决这一类问题而诞生 ...
随机推荐
- 关于SQL注入和如何防止
之前在笔试的时候没有很好的答出这个问题,因此我要总结一下问题,以免日后继续在这个地方跌倒,以下是自己的理解,如有错误请指出 一.什么是SQL注入 SQL注入就是服务器在根据业务去处理数据库的时候,客户 ...
- Service实时向Activity传递数据案例
转自 http://www.cnblogs.com/linjiqin/p/3147764.html 演示一个案例,需求如下:在Service组件中创建一个线程,该线程用来生产数值,每隔1秒数值自动加1 ...
- [转]extjs组件添加事件监听的三种方式
原文地址:http://blog.csdn.net/y6300023290/article/details/18989635 1.在定义组件配置的时候设置 xtype : 'textarea', na ...
- jQuery中的100个技巧
1.当document文档就绪时执行JavaScript代码. 我们为什么使用jQuery库呢?原因之一就在于我们可以使jQuery代码在各种不同的浏览器和存在bug的浏览器上完美运行. < ...
- POJ 3204 Ikki's Story I - Road Reconstruction
Ikki's Story I - Road Reconstruction Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 7 ...
- adb工具获取appPackage和appActivity
1,手机连接电脑,打开手机调试功能,并运行待测试APP,终端执行: adb shell 2,接着,执行: dumpsys window windows | grep -E 'mFocusedApp' ...
- VPS服务商
1.vpsee http://www.vpsee.com 2.vps侦探 http://www.vpser.net/
- lucene+IKAnalyzer实现中文纯文本检索系统
首先IntelliJ IDEA中搭建Maven项目(web):spring+SpringMVC+Lucene+IKAnalyzer spring+SpringMVC搭建项目可以参考我的博客 整合Luc ...
- Hibernate(Control)
案例:http://blog.csdn.net/jiuqiyuliang/article/details/39380465 对象关系映射框架,它对JDBC进行了轻量级的对象封装,可以使用对象编程思维来 ...
- 怎么把电脑的word,txt,pdf等文件拷贝到iPhone手机上
之前都是用的qq什么的传文件,电脑发送到qq上.今天尝试了一下用itunes把电脑上的文件夹弄到iPhone上. 1.首先,打开电脑的偏好设置,找到共享如图: 打开它,勾选文件共享. 2.把手机和电脑 ...