享元模式

模式定义

享元模式(Flyweight),运用共享技术有效的支持大量细粒度的对象。

模式动机

  • 如果一个应用使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用。
  • 当对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享内存对象取代很多组对象,此时可以考虑使用享元模式。

UML类图

源码实现

  • piece.h
#include <string>
enum Color
{
white,
black
};
class Piece
{
public:
Piece(Color color);
void setPoint(int x, int y);
Color GetColor() const;
public:
int m_X;
int m_Y; private:
Color m_Color;
};
  • piece.cpp
#include "piece.h"

Piece::Piece(Color color)
:m_Color(color)
{ } void Piece::setPoint(int x, int y)
{
m_X = x;
m_Y = y;
} Color Piece::GetColor() const
{
return m_Color;
}
  • checkerboard.h
#include <string>
#include "piece.h"
class CheckerBoard
{
public:
CheckerBoard();
void Draw();
void refresh();
void GetPiece(const Piece& piece); private:
std::string m_Checker;
};
  • checkerboard.cpp
#include <iostream>
#include <string.h>
#include "checkerboard.h" CheckerBoard::CheckerBoard()
{
for(int m = 0; m < 20; ++m)
{
for(int n = 0; n < 20; ++n)
m_Checker.append("o");
m_Checker.append("\n");
}
} void CheckerBoard::Draw()
{
std::cout << m_Checker;
} void CheckerBoard::refresh()
{
system("cls");
std::cout << m_Checker;
} void CheckerBoard::GetPiece(const Piece& piece)
{
int pos;
pos = (piece.m_Y * 21) + piece.m_X; if(piece.GetColor() == Color::white)
m_Checker.replace(pos, 1, "-");
else if(piece.GetColor() == Color::black)
m_Checker.replace(pos, 1, "+");
}
  • piecefactory.h
#include <map>
#include "piece.h"
class PieceFactory
{
public:
PieceFactory();
Piece *find(Color color);
private:
std::map<Color, Piece*> m_PiecesMap;
};
  • piecefactory.cpp
#include <memory>
#include "piecefactory.h" PieceFactory::PieceFactory()
{ } Piece *PieceFactory::find(Color color)
{
auto piece = m_PiecesMap.find(color);
if(piece != m_PiecesMap.end()){
return piece->second;
}
else
{
Piece* p = new Piece(color);
m_PiecesMap[color] = p;
return p;
}
}
  • main.cpp
/************************************
* @brief : 享元模式
* @author : wzx
* @date : 2020-07-16
* @project : FlyWeight
*************************************/
#include <iostream>
#include <random>
#include <time.h>
#include <thread>
#include <unistd.h>
#include "checkerboard.h"
#include "piecefactory.h"
#include "piece.h" using namespace std; void GeneratePoint(Piece* p)
{//随机数生成有点问题
std::mt19937 rnd(time(0));
p->m_X = rnd()%20;
p->m_Y = rnd()%20;
} int main()
{
CheckerBoard board;
board.Draw(); PieceFactory factory;
for(int n = 0; n < 20; ++n)
{
Piece* p1 = factory.find(Color::black);
GeneratePoint(p1); sleep(1); Piece* p2 = factory.find(Color::white);
GeneratePoint(p2); board.GetPiece(*p2);
board.GetPiece(*p1);
board.refresh();
} return 0;
}
  • 运行结果

oooooooooooooooooooo

oooooooooo+ooooooooo

-+oooooooooooooooooo

oooooooooooooooooooo

ooooooo-oooo+oo+oooo

oooooooooooooooooooo

o+oooooooooooooooooo

oooo++oo+ooooooooooo

注:随机数生成算法有点问题,这里忽略最终结果

优点

模式的优点

  • 享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本都是相同的,有时就能够受大幅度地减少需要实例化的类的数量。如果能把哪些参数移到类实例的外面,在方法调用的时候将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。

缺点

模式的缺点

  • 使用享元模式需要维护一个记录了系统已有的所有享元的列表,而这本身需要耗费资源。
  • 享元模式使得系统更加的复杂,为了使对象可以共享,需要将一些状态外部化,这是得程序的逻辑复杂化。因此,应当在有足够多的对象实例可供共享时才值得使用享元模式。

享元模式(c++实现)的更多相关文章

  1. Flyweight(享元模式)

    import java.util.Hashtable; /** * 享元模式 * @author TMAC-J * 享元模式一般和工厂模式一起使用,但此处为了更好说明,只用享元模式 * 定义:享元模式 ...

  2. 设计模式(十二)享元模式(Flyweight Pattern)

    一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非 ...

  3. 设计模式--享元模式Flyweight(结构型)

    一.享元模式 在一个系统中如果有多个相同的对象,这些对象有部分状态是可以共享的,我们运用共享技术就能有效地支持大量细粒度的对象. 二.例子 举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子. ...

  4. java享元模式(flyweight)

    有个问题: Integer i1 = 12; Integer i2 = 12; System.out.println(i1 == i2);//输出true Integer i1 = 130; Inte ...

  5. 享元模式 - Flyweight

    Flyweight(享元模式) 定义 GOF:运用共享技术有效地支持大量细粒度的对象. GOF的定义比较专业化,通俗来说,当你有大量相似的实例时,你把其中相同的实例取出来共享. 例子 在你的游戏场景中 ...

  6. C#设计模式-享元模式

    在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非常严重,然 ...

  7. C#设计模式系列:享元模式(Flyweight)

    当频繁地从数据源读取数据时,读出的内容存在重复,那么需要使用享元模式(Flyweight)来提高内存效率,Flyweight模式将节省更多空间,共享的Flyweight越多,空间节省越大. 1.享元模 ...

  8. javascript - 享元模式

    享元模式笔记  运用共享技术有效的支持大量的细粒度对象,避免对象间拥有相同内容造成多余的开销  享元模式主要还是对其数据.方法共享分离,它将数据和方法分成内部数据.内部方法和外部数据.外部方法.  内 ...

  9. 设计模式C#实现(十三)——享元模式(蝇量模式)

    意图 0 适用性 1 结构 2 实现 3 效果 4 参考 5 意图 运用共享技术有效地支持大量细粒度的对象. 适用性 当以下情况都成立时使用: 一个程序使用了大量的对象 完全由于使用大量对象造成很大存 ...

  10. 享元模式/Flyweight模式/对象结构型/设计模式

    flyweight 享元模式(对象结构型) Flyweight在拳击比赛中指最轻量级,即"蝇量级"或"雨量级",这里选择使用"享元模式"的意 ...

随机推荐

  1. linux kernel update

    linux内核升级 最近HW行动,报出来的linux系统内核漏洞,环境中全部是2.6.32-431.el6.x86_64的主机,需要全部升级到754版本,这也是第一次进行内核升级操作. 先找了一台和生 ...

  2. Spark3.0分布,Structured Streaming UI登场

    近日,在Spark开源十周年之际,Spark3.0发布了,这个版本大家也是期盼已久.登录Spark官网,最新的版本已经是3.0.而且不出意外,对于Structured Streaming进行了再一次的 ...

  3. 图解leetcode5-10 | 和233酱一起刷leetcode系列(2)

    本周我们继续来看5道磨人的小妖精,图解leetcode6-10- 多说一句,leetcode10 杀死了233酱不少脑细胞... 另: 沉迷算法,无法自拔.快来加入我们吧! 别忘了233酱的一条龙服务 ...

  4. elasticSearch中集群状态的guan'l

    es中集群出现上面的问题一般是磁盘空间不够引起的,就是node节点所在的磁盘空间不足引起的 es整个集群放在c盘,都快满了 说明es的磁盘已经快被使用完了,我们可以临时更新下磁盘空间大小 修改 ES分 ...

  5. Python3-算法-选择排序

    选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完. ...

  6. 关于数据库客户端navicat创建新连接失败的问题

    如图是navicat创建新连接的截图: 我就有一个疑问了,主机填localhost或者127.0.0.1都是本机,自然是可以连接成功的,那如果填本机的IP地址会怎样呢? 如下图,出现了报错: 说我的访 ...

  7. python 给视频添加马赛克

    用法: 1. 创建空文件夹:imgs 2. 将倒数第三行中的"222056.mov"改为你的视频路径,如:"a.mov" 3. 运行以下代码 4. 稍等片刻,鼠 ...

  8. (私人收藏)古风PPT高级灰蓝传艺

    古风PPT高级灰蓝传艺 https://pan.baidu.com/s/1ADgTfif8i6JqKORLXhTHHgn05p

  9. (私人收藏)java实例、知识点、面试题、SHH、Spring、算法、图书管理系统、综合参考

    https://pan.baidu.com/s/1hkmgJU6pf2sBjNV1NlOaNgr6l2 Java趣味编程100例java经典选择题100例及答案java面试题大全java排序算法大全j ...

  10. 二进制小数和IEEE浮点标准

    二进制小数 首先复习进位计数制的要素: 数码:用来表示进制数的元素.比如 二进制数的数码为:0,1 十进制数的数码为:0,1,2,3,4,5,6,7,8,9 十六进制数的数码为:0,1,2,3,4,5 ...