c++ 享元模式(flyweight)
举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子。现在要实现一个围棋程 序,该怎么办呢?首先要考虑的是棋子棋盘的实现,可以定义一个棋子的类,成员变量包括棋子的颜色、形状、位置等信息,另外再定义一个棋盘的类,成员变量中 有个容器,用于存放棋子的对象。下面给出代码表示:
棋子的定义,当然棋子的属性除了颜色和位置,还有其他的,这里略去。这两个属性足以说明问题。
#include <iostream>
#include <vector>
#include <string> enum PieceColor {BLACK,WHITE};
using namespace std; class Pos
{
public:
Pos(int x,int y):m_x(x),m_y(y)
{ }
int getX()
{
return m_x;
}
int getY()
{
return m_y;
}
private:
int m_x;
int m_y;
}; class Piece
{
public:
Piece(PieceColor color,Pos pos):m_color(color),m_pos(pos){};
~Piece() {}
virtual void Draw() {}
protected:
PieceColor m_color;
Pos m_pos; }; class WhitePiece : public Piece
{
public:
WhitePiece(PieceColor color, Pos pos):Piece(color,pos){}
~WhitePiece();
virtual void Draw() {
cout << "draw a white piece" << endl;
}
}; class BlackPiece:public Piece
{
public:
BlackPiece(PieceColor color,Pos pos):Piece(color,pos){}
~BlackPiece();
virtual void Draw(){ cout << "draw a black piece" <<endl; }
}; class PieceBoard
{
public:
PieceBoard(string black,string white):m_blackName(black),m_whiteName(white)
{ }
~PieceBoard() {
Clear();
}
void SetPiece(PieceColor color,Pos pos)
{
Piece * piece = NULL;
if(color == BLACK)
{
piece = new BlackPiece(color,pos);
std::cout << m_blackName << "在位置(" << pos.getX() << ","<<pos.getY() <<")" <<endl ;
piece->Draw();
m_pieceArray.push_back(piece);
}
else
{
piece = new WhitePiece(color,pos);
std::cout << m_whiteName << "在位置(" << pos.getX() << ","<<pos.getY() <<")" <<endl;
piece->Draw();
m_pieceArray.push_back(piece);
}
}
void Clear()
{
int size = m_pieceArray.size();
for(int i = ; i < size ; i++)
delete m_pieceArray[i];
}
private:
std::vector<Piece*> m_pieceArray;
std::string m_blackName;
std::string m_whiteName;
};
主函数:
#include "flyweight.h"
int main()
{
PieceBoard pieceBoard("A","B");
pieceBoard.SetPiece(BLACK,Pos(,));
pieceBoard.SetPiece(WHITE,Pos(,)); system("pause");
return ;
}
可以发现,棋盘的容器中存放了已下的棋子,而每个棋子包含棋子的所有属性。一盘棋往往需要含上百颗棋子,采用上面这种实现,占用的空间太大了。如何改进呢?用享元模式。其定义为:运用共享技术有效地支持大量细粒度的对象。
在围棋中,棋子就是大量细粒度的对象。其属性有内在的,比如颜色、形 状等,也有外在的,比如在棋盘上的位置。内在的属性是可以共享的,区分在于外在属性。因此,可以这样设计,只需定义两个棋子的对象,一颗黑棋和一颗白棋, 这两个对象含棋子的内在属性;棋子的外在属性,即在棋盘上的位置可以提取出来,存放在单独的容器中。相比之前的方案,现在容器中仅仅存放了位置属性,而原 来则是棋子对象。显然,现在的方案大大减少了对于空间的需求。
关注PieceBoard 的容器,之前是vector<Piece*> m_vecPiece,现在是vector<PiecePos> m_vecPos。这里是关键。
棋子的新定义,只包含内在属性:
#include <iostream>
#include <vector>
#include <string> enum PieceColor {BLACK,WHITE};
using namespace std; class Pos
{
public:
Pos(int x,int y):m_x(x),m_y(y)
{ }
int getX()
{
return m_x;
}
int getY()
{
return m_y;
}
private:
int m_x;
int m_y;
}; class Piece
{
public:
Piece(PieceColor color):m_color(color){};
~Piece() {}
virtual void Draw() {}
protected:
PieceColor m_color; }; class WhitePiece : public Piece
{
public:
WhitePiece(PieceColor color):Piece(color){}
~WhitePiece();
virtual void Draw() {
cout << "draw a white piece" << endl;
}
}; class BlackPiece:public Piece
{
public:
BlackPiece(PieceColor color):Piece(color){}
~BlackPiece();
virtual void Draw(){ cout << "draw a black piece" <<endl; }
}; class PieceBoard
{
public:
PieceBoard(string black,string white):m_blackName(black),m_whiteName(white)
{ }
~PieceBoard() {
Clear();
}
void SetPiece(PieceColor color,Pos pos)
{
Piece * piece = NULL;
if(color == BLACK)
{
piece = new BlackPiece(color);
std::cout << m_blackName << "在位置(" << pos.getX() << ","<<pos.getY() <<")" <<endl ;
piece->Draw();
m_blackPosArray.push_back(pos);
}
else
{
piece = new WhitePiece(color);
std::cout << m_whiteName << "在位置(" << pos.getX() << ","<<pos.getY() <<")" <<endl;
piece->Draw();
m_whitePosArray.push_back(pos);
}
}
void Clear()
{
//int size = m_pieceArray.size();
//for(int i = 0; i < size ; i++)
// delete m_pieceArray[i];
}
private:
std::vector<Pos> m_whitePosArray;
std::vector<Pos> m_blackPosArray;
std::string m_blackName;
std::string m_whiteName;
};
主函数:
#include "flyweight.h"
int main()
{
PieceBoard pieceBoard("A","B");
pieceBoard.SetPiece(BLACK,Pos(,));
pieceBoard.SetPiece(WHITE,Pos(,)); system("pause");
return ;
}
c++ 享元模式(flyweight)的更多相关文章
- 二十四种设计模式:享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...
- 设计模式(十)享元模式Flyweight(结构型)
设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
- 享元模式 FlyWeight 结构型 设计模式(十五)
享元模式(FlyWeight) “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...
- 享元模式-Flyweight(Java实现)
享元模式-Flyweight 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. 本文中的例子如下: 使用享元模式: 小明想看编程技术的书, ...
- Java享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern)主要用于减少创建的对象数量,并减少内存占用并提高性能. 这种类型的设计模式属于结构模式,因为该模式提供了减少对象计数的方法,从而改善应用的对象结构. 享元 ...
- 设计模式-11享元模式(Flyweight Pattern)
1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...
- 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 享元模式 - Flyweight
Flyweight(享元模式) 定义 GOF:运用共享技术有效地支持大量细粒度的对象. GOF的定义比较专业化,通俗来说,当你有大量相似的实例时,你把其中相同的实例取出来共享. 例子 在你的游戏场景中 ...
- 享元模式/Flyweight模式/对象结构型/设计模式
flyweight 享元模式(对象结构型) Flyweight在拳击比赛中指最轻量级,即"蝇量级"或"雨量级",这里选择使用"享元模式"的意 ...
随机推荐
- worldpress自定义页面
一:wordpress制作自定义页面的方法 有时候我们需要制作一些个性化的页面,而不是直接用wordpress的page页面模板.这时候我们就需要自已写一个页面出来.下面介绍一下制作流程: 第一步:制 ...
- 修改 CentOS 中的 repo
修改 CentOS 中的 repo 原因 由于安装 odoo 10 太慢,因为服务器是国外的. 修改 进入 repo 文件夹 cd /etc/yum.repos.d/ ls 可以看到所有的源.
- Hadoop MapReduce 操作 统计词频
1.准备文件并设置编码格式为UTF-8并上传Linux 2.新建一个Java Project 3.导入jar 4.编写Map()和Reduce() 5.将代码输出成jar 6.在linux中启动hdf ...
- Avro和Thrift区别(未完待续)
两者都是优秀的序列化框架: Avro创造之初是Hadoop之父Doug为了创造一种更加快捷的序列化方案(此时已经有了thrift),用于Hadoop的HDFS的文件序列化问题. Thrift一个成熟的 ...
- CSS内容简单归纳
具体内容请查阅<CSS参考手册> 一.CSS模块介绍 1.1 CSS1中定义了网页基本属性 字体.颜色.补白.基本选择器等 1.2 CSS2中在CSS1的基础上添加了高级功能 浮动和定位. ...
- linux 下apache 停止、重启等操作
基本的操作方法:本文假设你的apahce安装目录为/usr/local/apache2,这些方法适合任何情况 apahce启动命令:推荐/usr/local/apache2/bin/apachectl ...
- Java堆栈解析
1.RAM和ROM区别RAM-RamdomAccessMemory随机存取存储器(断电后数据会丢失),高速存取,读写时间相等,且与地址无关,如计算机内存等. ROM-Read Only Memory只 ...
- UI“三重天”之实践Uiautomator1
说起来Uiautomator也有一年没碰过了.借此来回顾.总结一下. 也是阅读<精通APP自动化测试>一书.实践出真知的一个框架.编写了部分移动端UI自动化脚本.后续再深入学习. 虽然现在 ...
- 准确计算Java中对象的大小
由于在项目中需要大致计算一下对象的内存占用率(Hadoop中的Reduce端内存占用居高不下却又无法解释),因此深入学习了一下如何准确计算对象的大小. 使用system.gc()和java.lang. ...
- 第三章:Hadoop简介及配置Hadoop-1.2.1,hbase-0.94.13集群
前面给大家讲了怎么安装Hadoop,肯定会有人还是很迷茫,装完以后原来就是这个样子,但是怎么用,下面,先给大家讲下Hadoop简介:大致理解下就OK了 hadoop是一个平台,提供了庞大的存储和并行计 ...