享元模式(c++实现)
享元模式
模式定义
享元模式(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++实现)的更多相关文章
- Flyweight(享元模式)
import java.util.Hashtable; /** * 享元模式 * @author TMAC-J * 享元模式一般和工厂模式一起使用,但此处为了更好说明,只用享元模式 * 定义:享元模式 ...
- 设计模式(十二)享元模式(Flyweight Pattern)
一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非 ...
- 设计模式--享元模式Flyweight(结构型)
一.享元模式 在一个系统中如果有多个相同的对象,这些对象有部分状态是可以共享的,我们运用共享技术就能有效地支持大量细粒度的对象. 二.例子 举个围棋的例子,围棋的棋盘共有361格,即可放361个棋子. ...
- java享元模式(flyweight)
有个问题: Integer i1 = 12; Integer i2 = 12; System.out.println(i1 == i2);//输出true Integer i1 = 130; Inte ...
- 享元模式 - Flyweight
Flyweight(享元模式) 定义 GOF:运用共享技术有效地支持大量细粒度的对象. GOF的定义比较专业化,通俗来说,当你有大量相似的实例时,你把其中相同的实例取出来共享. 例子 在你的游戏场景中 ...
- C#设计模式-享元模式
在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非常严重,然 ...
- C#设计模式系列:享元模式(Flyweight)
当频繁地从数据源读取数据时,读出的内容存在重复,那么需要使用享元模式(Flyweight)来提高内存效率,Flyweight模式将节省更多空间,共享的Flyweight越多,空间节省越大. 1.享元模 ...
- javascript - 享元模式
享元模式笔记 运用共享技术有效的支持大量的细粒度对象,避免对象间拥有相同内容造成多余的开销 享元模式主要还是对其数据.方法共享分离,它将数据和方法分成内部数据.内部方法和外部数据.外部方法. 内 ...
- 设计模式C#实现(十三)——享元模式(蝇量模式)
意图 0 适用性 1 结构 2 实现 3 效果 4 参考 5 意图 运用共享技术有效地支持大量细粒度的对象. 适用性 当以下情况都成立时使用: 一个程序使用了大量的对象 完全由于使用大量对象造成很大存 ...
- 享元模式/Flyweight模式/对象结构型/设计模式
flyweight 享元模式(对象结构型) Flyweight在拳击比赛中指最轻量级,即"蝇量级"或"雨量级",这里选择使用"享元模式"的意 ...
随机推荐
- 使用vscode 开发go项目的最新姿势. go版本1.14.2
使用了go 1.14.2. 版本, 再也不用建src, pkg, bin 目录了, 以及再也不用强制配置GOPATH了 前提条件: 必须是 go mod 项目. 在工程目录下, 执行这样的命令生成 ...
- Jenkins自动化测试脚本的构建
[准备环境] 自动化测试框架脚本 Linux下的Python环境 https://www.cnblogs.com/xinhua19/p/12836522.html [思路] 测试顺序是,测试通过 ...
- 定量度量程序复杂度的McCabe方法
[本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 请画出下面代码的 ...
- 谈谈spring-boot-starter-data-redis序列化
在上一篇中springboot 2.X 集成redis中提到了在spring-boot-starter-data-redis中使用JdkSerializationRedisSerializerl来实现 ...
- Java WebService _CXF、Xfire、AXIS2、AXIS1_四种发布方式(优缺点对比)
xis,axis2,Xfire以及cxf对比 http://ws.apache.org/axis/ http://axis.apache.org/axis2/java/core/ http://xfi ...
- 题解 - 【NOI2015】维修数列
题面大意: 使用平衡树维护一个数列,支持插入,修改,删除,翻转,求和,求最大和这 \(6\) 个操作. 题意分析: Splay 裸题,几乎各种操作都有了,这个代码就发给大家当个模板吧. 最后求最大和的 ...
- 同步/异步/阻塞/非阻塞/BIO/NIO/AIO各种情况介绍
常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...
- Python3-configparser模块-配置文件解析器
Python3中的configparser模块主要用于处理类似于windows ini 文件结构的配置文件 1.configparser模块提供实现基本配置语言的ConfigParser类 2.配置文 ...
- 03 . 二进制部署kubernetes1.18.4
简介 目前生产部署kubernetes集群主要两种方式 kubeadm Kubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群 ...
- 入门大数据---Kafka简介
一.简介 ApacheKafka 是一个分布式的流处理平台.它具有以下特点: 支持消息的发布和订阅,类似于 RabbtMQ.ActiveMQ 等消息队列: 支持数据实时处理: 能保证消息的可靠性投递: ...