享元模式

定义

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

享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象。就是当一个系统中有大量的重复对象的时候,如果这些对象是不可变对象,我们就可以使用

享元模式,将这些对象设计成享元,在内存只保存一份,供需要的代码使用,这样能减少内存中对象的数量,起到节省内存的作用。实际上,不仅仅相同对象可以设计成享元,对于相似对象,我们也可以将这些对象中相同的部分(字段)提取出来,设计成享元,让这些大量相似对象引用这些享元。

不可变对象是函数初始化之后,他的状态不会改变了,也就是不会存在被修改的情况。

优点

大大减少对象的创建,降低系统的内存,使效率提高。

缺点

提高了系统的复杂度

适用场景

一个系统中有大量相同或者相似的对象,使用这些对象,会造成内存的大量消耗,这时候可以考虑使用享元模式

代码实现

我们都下过象棋,对于象棋一共有32枚棋子,每方各16枚。每次下棋使用的都是这32枚棋子,只是每次移动的棋子的位置。

那么这32枚棋子就可以作为享元,每次下棋就不用重新初始化生成棋子。只需在棋盘中放置棋子的位子,下棋的时候,更改位置即可。

// ChessPieceUnit ...
type ChessPieceUnit struct {
id int
text string
color string
} var pieces map[int]*ChessPieceUnit func init() {
pieces = make(map[int]*ChessPieceUnit, 32)
pieces[1] = &ChessPieceUnit{
id: 1,
text: "马",
color: "BLACK",
}
pieces[2] = &ChessPieceUnit{
id: 2,
text: "炮",
color: "BLACK",
}
// ...
} func getChessPiece(chessPieceId int) *ChessPieceUnit {
return pieces[chessPieceId]
} type ChessPiece struct {
chessPieceUnit *ChessPieceUnit
positionX int
positionY int
} func newChessPiece(chessPieceId int, positionX, positionY int) *ChessPiece {
return &ChessPiece{
chessPieceUnit: getChessPiece(chessPieceId),
positionX: positionX,
positionY: positionY,
}
} // 棋盘
type ChessBoard struct {
chessPieces map[int]*ChessPiece
} func (cb *ChessBoard) InitChessBoard() {
cb.chessPieces = make(map[int]*ChessPiece, 32)
cb.chessPieces[1] = newChessPiece(1, 0, 1)
cb.chessPieces[2] = newChessPiece(2, 0, 2)
// ...
} // Move 下棋
func (cb *ChessBoard) Move(chessPieceId int, positionX, positionY int) {
// TODO
}

享元模式和单例模式的区别

单例模式:一个类只能创建一个对象。

享元模式:一个类可以创建多个对象,每个对象被多处代码引用共享。实际上,享元模式有点类似于之前讲到的单例的变体:多例。

单例对象可以是可变的。 享元对象是不可变的。

实现上差不多,不过设计意图不同,享元模式是为了对象复用,节省内存,而应用多例模式是为了限制对象的个数。

参考

【文中代码】https://github.com/boilingfrog/design-pattern-learning/tree/master/享元模式

【大话设计模式】https://book.douban.com/subject/2334288/

【极客时间】https://time.geekbang.org/column/intro/100039001

【享元模式】https://boilingfrog.github.io/2021/11/17/使用go实现享元模式/

设计模式学习-使用go实现享元模式的更多相关文章

  1. javascript设计模式学习之十二——享元模式

    一.享元模式的定义及使用场景 享元模式是为了解决性能问题而诞生的设计模式,这和大部分设计模式为了提高程序复用性的原因不太一样,如果系统中因为创建了大量类似对象而导致内存占用过高,享元模式就非常有用了. ...

  2. C#设计模式学习笔记:(11)享元模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7792973.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲结构型设计模式的第六个模式--享 ...

  3. .NET设计模式(13):享元模式(Flyweight Pattern)(转)

    摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价.那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面 ...

  4. Java 设计模式系列(十一)享元模式

    Java 设计模式系列(十一)享元模式 Flyweight 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 一.享元模式的结构 享元模式采用一个共享来避免大量拥有相同内容对 ...

  5. 设计模式之第12章-享元模式(Java实现)

    设计模式之第12章-享元模式(Java实现) “怎么回事,竟然出现了OutOfMemory的错误.鱼哥,来帮我看看啊.”“有跟踪错误原因么?是内存泄露么?”“不是内存泄露啊,具体原因不知道啊.对了,有 ...

  6. 深入探索Java设计模式(四)之享元模式

    享元模式适用于需要大量相同类型对象的情况.在此,设计布局可以减少创建多个对象的方式.对象在运行时会消耗资源,因此最好在内存中使用较少的对象.它减少了内存占用并利用了程序的整体性能.本文是在学习完优锐课 ...

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

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

  8. IOS设计模式学习(21)享元

    1 前言 在面向对象软件设计中,利用公共对象不仅能节省资源还能提高性能.共享的对象只能提供某些内在的信息,而不能用来识别对象.专门用于设计可共享对象的一种设计模式叫做享元模式(Flyweight pa ...

  9. 设计模式总结篇系列:享元模式(Flyweight)

    我们都知道,Java中的String类具有如下特性:String是一个不可变类,当直通过用字符串方式使用String对象时,Jvm实际上在内存中只存有一份,且存在字符串常量池中.当对字符串直接进行修改 ...

随机推荐

  1. kettle 多表全删全插同步数据 两种方案

    背景: 接到上级指示,要从外网某库把数据全部导入到内网,数据每天更新一次即可,大约几百万条数据,两个库结构一样,mysql的,两台数据库所在服务器都是windows server的,写个java接口实 ...

  2. join方法个人理解

    首先抛出对join的疑问 如果我有一个a线程,一个b线程 那此时 a.start(); b.start(); a.join(); b.join(); 是否意思是a线程先执行完,然后再执行b线程; 如果 ...

  3. 极简SpringBoot指南-Chapter01-如何用Spring框架声明Bean

    仓库地址 w4ngzhen/springboot-simple-guide: This is a project that guides SpringBoot users to get started ...

  4. 题解 Yet Another Number Sequence

    题目传送门 Description 给出 \(n,k\) ,求出: \[\sum_{i=1}^{n} f_i·i^k \] 其中 \(f_i\) 表示斐波拉契第 \(i\) 项.\(n\le 10^{ ...

  5. 洛谷3320 SDOI2015寻宝游戏(set+dfs序)(反向迭代器的注意事项!)

    被\(STL\)坑害了一个晚上,真的菜的没救了啊. 准确的说是一个叫\(reverse\ iterator\)的东西,就是我们经常用的\(rbegin()\) 有一个非常重要的性质 在反向迭代器中,+ ...

  6. 【Python123】练习1: Python基本语法元素 (第1周)

    实例1: 温度转换 这是"实例"题,与课上讲解实例相同,请作答检验学习效果.‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬ ...

  7. Windows内核开发-9-32位和64位的区别

    Windows内核开发-9-32位和64位的区别 32位的应用程序可以完美再64位的电脑上运行,而32位的内核驱动无法再64位的电脑上运行,或者64位的驱动无法在32位的应用程序上运行.这是为什么呢. ...

  8. Endian

    Endian 寻址 多字节对象被存储为连续的字节序列,对象的地址为所使用字节中最小的地址. 例如,假设一个类型为 int 的变量 a 的地址为 0x100,也就是说,地址表达式 &a 的值为 ...

  9. [软工顶级理解组] Beta阶段项目展示

    目录 团队成员 软件介绍 项目简介 预期典型用户 功能描述 预期目标用户数 用户反馈 团队管理 分工协作 项目管理 取舍平衡 代码管理 程序测试 代码规范 文档撰写 继续开发指导性 用户沟通 需求分析 ...

  10. 用cmd命令行创建vue项目模板

    1.进入cmd命令行 输入存放项目的位置 2.通过vue create 项目名称 创建项目 3.选择Manually select features 4.通过空格选中第1.2.5.6.7.去掉8 4. ...