【设计模式】第13节:结构型模式之“享元模式”

一、简介

所谓“享元”,顾名思义就是被共享的单元。享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象。

实现:通过工厂模式,在工厂类中,通过一个Map或者List来缓存已经创建好的享元对象,以达到复用的目的。把实例的共享状态和不共享状态分开。

二、UML类图

请添加图片描述

三、案例

以下是画图器画圆的场景,圆形只有黑色和红色两种,所以可以共享复用。

package main

import "fmt"

const (
	BLACK = 0
	RED   = 1
)

type CircleUnit struct {
	Color int
}

func NewCircleUnit(color int) CircleUnit {
	return CircleUnit{Color: color}
}

type CircleUnitFactory struct {
	CircleMap map[int]CircleUnit
}

func (cuf *CircleUnitFactory) Init() {
	blackCircle := NewCircleUnit(BLACK)
	redCircle := NewCircleUnit(RED)
	cuf.CircleMap = make(map[int]CircleUnit)
	cuf.CircleMap[blackCircle.Color] = blackCircle
	cuf.CircleMap[redCircle.Color] = redCircle
}

func (cuf *CircleUnitFactory) GetCircleUnit(color int) (CircleUnit, error) {
	cu, ok := cuf.CircleMap[color]
	if !ok {
		return cu, fmt.Errorf("color[%v] is not exist", color)
	}
	return cu, nil
}

type Circle struct {
	ID         int
	CircleUnit CircleUnit
	X          int
	Y          int
}

func NewCircle(id int, circleUnit CircleUnit, x, y int) Circle {
	circle := Circle{}
	circle.ID = id
	circle.CircleUnit = circleUnit
	circle.X = x
	circle.Y = y
	return circle
}

type DrawingBoard struct {
	CircleMap map[int]Circle
}

func (db *DrawingBoard) Init() {
	db.CircleMap = make(map[int]Circle)
}

func (db *DrawingBoard) Draw(circle Circle) {
	db.CircleMap[circle.ID] = circle
}

func (db *DrawingBoard) Show() {
	for k, v := range db.CircleMap {
		fmt.Printf("id: %v, color: %v, x: %v, y: %v\n", k, v.CircleUnit.Color, v.X, v.Y)
	}
}

func main() {
	circleUnitFactory := CircleUnitFactory{}
	circleUnitFactory.Init()
	drawingBoard := DrawingBoard{}
	drawingBoard.Init()

	black, _ := circleUnitFactory.GetCircleUnit(BLACK)
	red, _ := circleUnitFactory.GetCircleUnit(RED)
	drawingBoard.Draw(NewCircle(1, black, 1, 1))
	drawingBoard.Draw(NewCircle(2, red, 2, 2))
	drawingBoard.Draw(NewCircle(3, black, 3, 3))

	drawingBoard.Show()
}

四、对比

享元模式VS单例、缓存、对象池:应用单例模式是为了保证对象全局唯一。应用享元模式是为了实现对象复用,节省内存。缓存是为了提高访问效率,而非复用。池化技术中的“复用”理解为“重复使用”,主要是为了节省时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/109283.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 415 字符串相加 简单

题目 - 点击直达 1. 415 字符串相加 简单1. 题目详情1. 原题链接2. 题目要求3. 基础框架 2. 解题思路1. 思路分析2. 时间复杂度3. 代码实现 1. 415 字符串相加 简单 1. 题目详情 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。…

LeetCode题:88合并两个有序数组,283移动零,448找到所有数组中消失的数字

目录 88合并两个有序数组 1、题目要求 2、解题思路 (1)、暴力解法: (2)、双指针,使用第三数组的解法: 3、代码展示 (1)、暴力解法: (2&am…

画时钟(turtle库)

思路: 总体来看,分为两个部分:固定的表盘,和不断刷新的指针(和时间显示) 固定的表盘 我的表盘长这个样子: 分为三个部分:60个dot点(分、秒),12条…

漏洞复现--用友 畅捷通T+ .net反序列化RCE

免责声明: 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

树莓派基金会近日发布了新版基于 Debian 的树莓派操作系统

导读树莓派基金会(Raspberry Pi Foundation)近日发布了新版基于 Debian 的树莓派操作系统(Raspberry Pi OS),为树莓派单板电脑带来了新的书虫基础和一些重大变化。 新版 Raspberry Pi OS 的最大变化是它现在基于最新的…

竞赛选题 深度学习图像修复算法 - opencv python 机器视觉

文章目录 0 前言2 什么是图像内容填充修复3 原理分析3.1 第一步:将图像理解为一个概率分布的样本3.2 补全图像 3.3 快速生成假图像3.4 生成对抗网络(Generative Adversarial Net, GAN) 的架构3.5 使用G(z)生成伪图像 4 在Tensorflow上构建DCGANs最后 0 前言 &#…

《数字图像处理-OpenCV/Python》连载(33)使用掩模图像控制处理区域

**本书京东优惠购书链接:https://item.jd.com/14098452.html** **本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html** 第 5 章 图像的算术运算 在OpenCV中,图像是以Numpy数组格式存储的,图像的算术运…

大数据Flink(一百零三):SQL 表值聚合函数(Table Aggregate Function)

文章目录 SQL 表值聚合函数(Table Aggregate Function) SQL 表值聚合函数(Table Aggregate Function) Python UDTAF,即 Python TableAggregateFunction。Python UDTAF 用来针对一组数据进行聚合运算,比如同一个 window 下的多条数据、或者同一个 key 下的多条数据等,与…

grafana InfluxDB returned error: error reading influxDB 400错误解决

问题: 如图提示错误解决 确认自己的docker容器是否配置了以下3个字段 DOCKER_INFLUXDB_INIT_USERNAMExxx DOCKER_INFLUXDB_INIT_PASSWORDyyy DOCKER_INFLUXDB_INIT_ADMIN_TOKENzzz 如果有,在grafana中需要添加header配置Header: Authorization , Value…

docker应用部署---nginx部署的配置

1. 搜索nginx镜像 docker search nginx2. 拉取nginx镜像 docker pull nginx3. 创建容器,设置端口映射、目录映射 # 在/root目录下创建nginx目录用于存储nginx数据信息 mkdir ~/nginx cd ~/nginx mkdir conf cd conf# 在~/nginx/conf/下创建nginx.conf文件,粘贴下…

VScode 调试 linux内核

VScode 调试 linux内核 这里调试的 linux 内核是通过 LinuxSD卡(rootfs)运行的内核 gdb 命令行调试 编辑 /home/tyustli/.gdbinit 文件,参考 【GDB】 .gdbinit 文件 set auto-load safe-path /home/tyustli/code/open_source/kernel/linux-6.5.7/.gdbinit在 lin…

C笔记:引用调用,通过指针传递

代码 #include<stdio.h> int max1(int num1,int num2) {if(num1 < num2){num1 num2;}else{num2 num1;} } int max2(int *num1,int *num2) {if(num1 < num2){*num1 *num2; // 把 num2 赋值给 num1 }else{*num2 *num1;} } int main() {int num1 0,num2 -2;int…

【AD9361 数字接口CMOS LVDSSPI】D 串行数据之SPI

【AD9361 数字接口CMOS &LVDS&SPI】D部分 接续 【AD9361 数字接口CMOS &LVDS&SPI】A 并行数据之CMOS 串行外设接口&#xff08;SPI&#xff09; SPI总线为AD9361的所有数字控制提供机制。每个SPI寄存器的宽度为8位&#xff0c;每个寄存器包含控制位、状态监视…

进阶设计一(DDR3)——FPGA学习笔记<?>

一.简介 DDR3 SDRAM&#xff0c;以其单位存储量大、高数据带宽、读写速度快、价格相对便宜等优点 吸引了大批客户&#xff0c;占领市场较大份额。同时&#xff0c;作为内存条中不可缺少的一部分&#xff0c;DDR3 SDRAM 在计算机领域也占有一席之地。 要掌握 DDR3 SDRAM…

什么是 Node.js

目标 什么是 Node.js&#xff0c;有什么用&#xff0c;为何能独立执行 JS 代码&#xff0c;演示安装和执行 JS 文件内代码 讲解 Node.js 是一个独立的 JavaScript 运行环境&#xff0c;能独立执行 JS 代码&#xff0c;因为这个特点&#xff0c;它可以用来编写服务器后端的应用…

能量管理系统(EMS):新能源储能行业的智能化大脑

导语&#xff1a;能源管理系统&#xff08;EMS&#xff09;是新能源储能行业中一种关键的智能化技术。它的作用类似于大脑&#xff0c;能够监控、控制和优化能源系统的运行&#xff0c;为储能设施提供高效稳定的能源管理。本文将介绍能量管理系统的基本概念、功能和应用。 一、…

51单片机晶体管数字编码

51单片机 单片机型号&#xff1a;STC86C52RC/LE52RC 晶体管 数字编码 数字P0P1P2P3P4P5P6P7011111100101100000211011010311110010401100110510110110610111110711100000811111110911110110 00011 11110x3F10000 01100x0620101 10110x5B30100 11110x4F40110 01100x6650110 110…

【LLM】sft和pretrain数据处理和筛选方法

note 痛点&#xff1a;训练垂直领域模型&#xff0c;sft数据和增量pretrain数据质量把控很重要 当数据不够时&#xff0c;通过self-instruct等方法造多样化的数据当数据很多时&#xff0c;需要清洗/筛选出高质量数据 文章目录 note一、sft数据的筛选策略1.1 使用self-instruc…

Arhas 常用命令

watch 函数执行数据观测: location 会有三种值 AtEnter&#xff0c;AtExit&#xff0c;AtExceptionExit。 对应函数入口&#xff0c;函数正常 return&#xff0c;函数抛出异常。 result 表示观察表达式的值&#xff1a; {params,returnObj,throwExp} eg: 查看是某个方法的参…

hadoop权威指南第四版

第一部分 HaDOOP基础知识 1.1 面临的问题 存储越来越大&#xff0c;读写跟不上。 并行读多个磁盘。 问题1 磁盘损坏 – 备份数据HDFS 问题2 读取多个磁盘用于分析&#xff0c;数据容易出错 --MR 编程模型 1.2 衍生品 1 在线访问的组件是hbase 。一种使用hdfs底层存储的模型。…