享元模式

定义

享元模式(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. HashMap扩容和ConcurrentHashMap

    HashMap 存储结构 HashMap是数组+链表+红黑树(1.8)实现的. (1)Node[] table,即哈希桶数组.Node是内部类,实现了Map.Entry接口,本质是键值对. stati ...

  2. 高德最佳实践:Serverless 规模化落地有哪些价值?

    作者 | 何以然(以燃) 导读:曾经看上去很美.一直被观望的 Serverless,现已逐渐进入落地的阶段.今年的"十一出行节",高德在核心业务规模化落地 Serverless,由 ...

  3. bzoj4552排序(线段树,二分)

    题目大意 给定一个长度为n的序列,有m个操作,操作包括两种: \(0\ l\ r\)区间[l,r]的数字升序排序 \(1\ l\ r\)区间[l,r]的数字降序排序 最后询问在q位置上的数是多少? 其 ...

  4. SpringBoot-集成SpringSecurity

    在 Web 开发中,安全一直是非常重要的一个方面. 安全虽然属于应用的非功能性需求,但是从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中. Spring Security官网 ...

  5. Catch That Cow 经典广搜

    链接:http://poj.org/problem?id=3278 题目: Farmer John has been informed of the location of a fugitive co ...

  6. Linux 命令后&的作用

    cp $filename /dev/ & & 代表非阻塞方式拷贝文件,如果不加& 则必须等到执行完该指令后才能执行后来的指令.

  7. 974.和可被K整除的子数组

    题目 给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续.非空)子数组的数目. 示例: 输入:A = [4,5,0,-2,-3,1], K = 5 输出:7 解释: 有 7 个子数组满足其元 ...

  8. 面试题 08.12. N皇后

    题目 设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行.不同列,也不在对角线上.这里的"对角线"指的是所有的对角线,不只是平分整个棋盘的那两条对角 ...

  9. SpringBoot整合Prometheus

    SpringBoot整合Prometheus 一.需求 二.实现步骤 1.引入jar包 2.application.prometheus文件配置 3.查看指标数据 4.接入到 prometheus 中 ...

  10. Noip模拟12 2021.7.12

    T1 interval 亏得昨天晚上改掉了T3并且理解了单调栈,今天一扫这题目就知道要用啥了. 先预处理出以a[i]为最大值的最大左右区间.然后再将a[i]取%!!!是的,要不然会影响单调栈的使用.. ...