设计模式学习-使用go实现享元模式
享元模式
定义
享元模式(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实现享元模式的更多相关文章
- javascript设计模式学习之十二——享元模式
一.享元模式的定义及使用场景 享元模式是为了解决性能问题而诞生的设计模式,这和大部分设计模式为了提高程序复用性的原因不太一样,如果系统中因为创建了大量类似对象而导致内存占用过高,享元模式就非常有用了. ...
- C#设计模式学习笔记:(11)享元模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7792973.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲结构型设计模式的第六个模式--享 ...
- .NET设计模式(13):享元模式(Flyweight Pattern)(转)
摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价.那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面 ...
- Java 设计模式系列(十一)享元模式
Java 设计模式系列(十一)享元模式 Flyweight 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 一.享元模式的结构 享元模式采用一个共享来避免大量拥有相同内容对 ...
- 设计模式之第12章-享元模式(Java实现)
设计模式之第12章-享元模式(Java实现) “怎么回事,竟然出现了OutOfMemory的错误.鱼哥,来帮我看看啊.”“有跟踪错误原因么?是内存泄露么?”“不是内存泄露啊,具体原因不知道啊.对了,有 ...
- 深入探索Java设计模式(四)之享元模式
享元模式适用于需要大量相同类型对象的情况.在此,设计布局可以减少创建多个对象的方式.对象在运行时会消耗资源,因此最好在内存中使用较少的对象.它减少了内存占用并利用了程序的整体性能.本文是在学习完优锐课 ...
- 设计模式(十二)享元模式(Flyweight Pattern)
一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非 ...
- IOS设计模式学习(21)享元
1 前言 在面向对象软件设计中,利用公共对象不仅能节省资源还能提高性能.共享的对象只能提供某些内在的信息,而不能用来识别对象.专门用于设计可共享对象的一种设计模式叫做享元模式(Flyweight pa ...
- 设计模式总结篇系列:享元模式(Flyweight)
我们都知道,Java中的String类具有如下特性:String是一个不可变类,当直通过用字符串方式使用String对象时,Jvm实际上在内存中只存有一份,且存在字符串常量池中.当对字符串直接进行修改 ...
随机推荐
- HashMap扩容和ConcurrentHashMap
HashMap 存储结构 HashMap是数组+链表+红黑树(1.8)实现的. (1)Node[] table,即哈希桶数组.Node是内部类,实现了Map.Entry接口,本质是键值对. stati ...
- 高德最佳实践:Serverless 规模化落地有哪些价值?
作者 | 何以然(以燃) 导读:曾经看上去很美.一直被观望的 Serverless,现已逐渐进入落地的阶段.今年的"十一出行节",高德在核心业务规模化落地 Serverless,由 ...
- bzoj4552排序(线段树,二分)
题目大意 给定一个长度为n的序列,有m个操作,操作包括两种: \(0\ l\ r\)区间[l,r]的数字升序排序 \(1\ l\ r\)区间[l,r]的数字降序排序 最后询问在q位置上的数是多少? 其 ...
- SpringBoot-集成SpringSecurity
在 Web 开发中,安全一直是非常重要的一个方面. 安全虽然属于应用的非功能性需求,但是从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中. Spring Security官网 ...
- Catch That Cow 经典广搜
链接:http://poj.org/problem?id=3278 题目: Farmer John has been informed of the location of a fugitive co ...
- Linux 命令后&的作用
cp $filename /dev/ & & 代表非阻塞方式拷贝文件,如果不加& 则必须等到执行完该指令后才能执行后来的指令.
- 974.和可被K整除的子数组
题目 给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续.非空)子数组的数目. 示例: 输入:A = [4,5,0,-2,-3,1], K = 5 输出:7 解释: 有 7 个子数组满足其元 ...
- 面试题 08.12. N皇后
题目 设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行.不同列,也不在对角线上.这里的"对角线"指的是所有的对角线,不只是平分整个棋盘的那两条对角 ...
- SpringBoot整合Prometheus
SpringBoot整合Prometheus 一.需求 二.实现步骤 1.引入jar包 2.application.prometheus文件配置 3.查看指标数据 4.接入到 prometheus 中 ...
- Noip模拟12 2021.7.12
T1 interval 亏得昨天晚上改掉了T3并且理解了单调栈,今天一扫这题目就知道要用啥了. 先预处理出以a[i]为最大值的最大左右区间.然后再将a[i]取%!!!是的,要不然会影响单调栈的使用.. ...