设计模式15——享元模式
写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。
享元模式(Flyweight)
是一种结构型模式。
目录
一、概述
1.1、先给出通用的UML图:
二、举例
2.1、简单举例认识此模式:
2.2、举例:
一、概述
1、运用共享技术有效地支持大量细粒度的对象;2、享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够大幅度地减少需要实例化的类的数量。如果能把那些参数转移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目;3、如果一个应用程序使用大量的对象,而大量的这些对象造成了很大的存储开销时;4、内部状态存储在享元对象(目标对象)中,它包含了独立于其他对象的信息,这些信息使得享元对象可以被分享;5、外部状态取决享元对象(目标对象)的所在场景,根据场景而变化,因为是动态变化的所以不能够共享。但有时会根据需要将外部状态传递给享元对象;6、对象的大多数状态可以是外部状态,如果可以从对象中删除外部状态,那么可以用相对较少的共享对象取代很多组对象;那么此时可以考虑使用享元模式。
(注1:‘粒度’是被用来描述对象大小的。如:我们将 淘宝应用程序 和 购物车功能 看做两个对象,那么我们可以说 淘宝 比起 购物车 粒度要大,或者说 购物车 比起 淘宝 粒度要小)
(注2:享元模式和原型模式都是针对一堆相似类对象。不同的是:享元模式是缩减它们从而减少储存开销;而原型模式是优化它们创建的方式从而减少新增和复制的时间开销。并且两种模式思想完全相反。)
1.1、先给出通用的UML图:
(对模式的简单认识将在下面简单举例认识此模式中说明)
二、举例
2.1、简单举例认识此模式:
2.1.1、假设王五和老刘都要访问博客网站,按照以往的思维,那肯定是要实例化两个博客网站的,如下:
2.1.2、那我们先进行初步的抽象,将博客对象都分为两部分,个人信息和网站功能:
2.1.3、我们可以发现,上述两个博客的实例对象,除了个人信息部分,其他地方都一样,此时我们就可想到享元模式,尝试将个人信息这部分转移出来,也就是将不同的地方拎出来,然后将相同的部分只保留一份:
2.1.4、对比上面两张图可以看到,节省了一个功能部分的存储空间。同理要是有10个人,就会有10个个人信息部分,但功能部分还是只有一份。通过这样的设计就达到了节省空间的目的。也就是把变与不变的地方分开来分析与设计。
此外:
- 目标对象(享元对象):博客网站
- 内部状态:功能部分
- 外部状态:个人信息部分
2.2、举例:
2.2.1、假设现有四个人,张三、李四、王五、老刘,其中张三和李四要访问淘宝,王五和老刘要访问博客,假设淘宝和博客功能一致,那么相比上面的举例,和上述一样将个人信息部分都拎出来,但要注意新加了个淘宝,我们可以得到:
这次是有两个网站实例淘宝、博客,和四个人的信息部分。再经过分析发现,博客和淘宝可以抽象出:它们都属于网站。这样可以把博客和淘宝当做网站名的外部状态分离出来。
2.2.2、对象之间的关系用UML图表示如下:
(具体的功能部分不是本例的重点,所以就假设淘宝和博客功能部分一样,或者说被抽象出去了)
此例将个人信息单独设计一个类,而淘宝和博客这个就只存储在String字符串中。而实际使用此模式时根据自己的需要可以灵活改变。
2.2.2、Java实现代码如下:
网站抽象类:
abstract class WebSite {public abstract void use(User user);
}
具体网站:
public class ConcreteWebSite extends WebSite {private String webName;public ConcreteWebSite(String webName) {this.webName = webName;}@Overridepublic void use(User user) {System.out.println("网站名:" + this.webName + ",用户名:" + user.getUserName());}
}
网站控制工厂:
public class WebSiteFactory {private HashMap<String, WebSite> hashMap = new HashMap<>();public WebSite getWebSiteCategory(String key) {if (!hashMap.containsKey(key)) {hashMap.put(key, new ConcreteWebSite(key));}return hashMap.get(key);}public int getWebSiteCount() {return hashMap.size();}
}
用户:
public class User {private String userName;public User(String userName) {this.userName = userName;}public String getUserName() {return userName;}
}
主程序(发起请求的类):
public class Main {public static void main(String[] args) {WebSiteFactory webSiteFactory = new WebSiteFactory();WebSite webSite1 = webSiteFactory.getWebSiteCategory("淘宝");webSite1.use(new User("张三"));WebSite webSite2 = webSiteFactory.getWebSiteCategory("淘宝");webSite2.use(new User("李四"));WebSite webSite3 = webSiteFactory.getWebSiteCategory("博客");webSite3.use(new User("王五"));WebSite webSite4 = webSiteFactory.getWebSiteCategory("博客");webSite4.use(new User("老刘"));System.out.println("网站总数为:" + webSiteFactory.getWebSiteCount());}
}
这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。
如果觉得本文还不错,就请点个赞吧!如果有建议,也请评论指教和讨论!
相关文章:

设计模式15——享元模式
写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。 享元模式(Flyweigh…...

多模态中的模态有哪些
“多模态”这个名字中的“模态”(modality),指的是不同的数据类型或信息源。在多模态大模型中,常见的模态包括: 文本模态: 包括自然语言文本、语音识别文本等。 图像模态: 指图像数据ÿ…...

Java练习题(八)
36.关于抽象类叙述正确的是? (B ) A.抽象类不能实现接口 B.抽象类必须有“abstract class”修饰 C.抽象类必须包含抽象方法 D.抽象类也有类的特性,可以被实例化 37.以下说法错误的是(C) A.数组是一个对象 B.数组不是一种原…...

Linux文本文件管理003
★排序、去重、统计★ 1)排序 sort -n按照数值排序 -r降序排列 2)去重 uniq 过滤相邻、重复的行 -c 对重复行计数 3)统计 wc 统计文件中的字节数、单词数、行数 -l 显示行数 今天通过使用grep、awk、cut指令和上面几个选项提取文本文件…...

uniapp Androud 离线打包升级APK,覆盖安装不更新问题
Android 打包时在assets/data/dcloud_control.xml文件中,如果配置debug"true" syncDebug"true",则consle打印有效,不然没有打印数据 <hbuilder debug"true" syncDebug"true"> <apps> …...

【算法实战】每日一题:设计一个算法,用最少数量的矩形覆盖一系列宽度为d、高度为w的矩形,且使用矩形不能超出边界
题目 设计一个算法,用最少数量的矩形覆盖一系列宽度为d、高度为w的矩形建筑物侧墙,且矩形不能超出边界。 核心思路 考虑这种结构 前面递增后面一个与前面的某个高度一致,这时候考虑最下面的覆盖(即都是从最下面向上覆盖&#…...

外贸仓库管理软件:海外仓效率大幅度提升、避免劳动力积压
随着外贸业务的不断发展,如何高效管理外贸仓库,确保货物顺利流转,订单顺利处理,就变得非常重要。 现在通常的解决方案都是通过引入外贸仓库管理软件,也就是我们常说的海外仓WMS系统来解决。 今天我们就系统的探讨一下…...

6.8 LIBBPF API(七,bpf_core_read.h 函数,定义,枚举)
一,函数 void * bpf_rdonly_cast (const void *obj, __u32 btf_id) __ksym __weak 二,定义 __CORE_RELO(src, field, info) __builtin_preserve_field_info((src)->field,BPF_FIELD_##info) __CORE_BITFIELD_PROBE_READ(dst, src, fld) bpf_probe_read_kernel( \ (v…...

电脑卸载linux安装windows后每次开机都出现grub
原因分析 这是因为电脑硬盘中还存在linux系统的引导程序,并且启动顺序还在windows之前,有时候通过bios根本找不到它的存在,以至于每次windows开机出现grub之后都要输入exit退出linux的引导之后才能使得电脑进入windows,这个有时会…...

总结 HTTPS 的加密流程
一、前言 http是为了解决http存在的问题而在http基础上加入了SSL/TSL,在HTTP/2中TCP三次握手后会进入SSL/TSL握手,当SSL/TSL建立链接后,才会进行报文的传输。 二、HTTPS的混合加密 我们先来认识密钥: 密钥是用于加密和解密数据…...

Spring的FactoryBean多例问题
关于spring bean,我们了解的最多的还是单例,而多例bean,除了平时我们自己new的那些多实例外(但不属于IOC管理了),几乎很少能用到,而在spring 层面,FactoryBean刚好是多例的一个体现,…...

[nextjs]推荐几个很好看的模板网站
最近在做网站,折腾了 vue 框架,然后发现了 nextjs 框架,感觉这个做出来的网站配色很好看,然后又开始研究这个 网站配色好看是因为用的 tailwindcss,找网站过程中,发现了几个很好看的模板网站,在这里推荐下,或许你也能用得上 推荐第一个网站是: https://tailspark.co/ 有组件,也…...

《当微服务遇上Ribbon:一场负载均衡的华丽舞会》
在微服务的厨房里,如何确保每一道服务都恰到好处?揭秘Spring Cloud Ribbon如何像大厨一样精心调配资源,让负载均衡变得像烹饪艺术一样简单! 文章目录 Spring Cloud Ribbon 详解1. 引言微服务架构中的负载均衡需求Spring Cloud Rib…...

简单随机数据算法
文章目录 一,需求概述二,实现代码三、测试代码四、测试结果五、源码传送六、效果演示 一,需求概述 系统启动时,读取一组图片数据,通过接口返回给前台,要求: 图片随机相邻图片不重复 二&#…...

js画思维导图代码2
这段代码是一个使用Vue.js和D3.js构建的树形图组件。它是一个Vue组件,用于创建和显示一个交互式的树形结构图。下面是对这段代码的简要分析: 模板部分 (<template>): 定义了组件的HTML结构,包括一个隐藏的提示框(#tooltip)和一个用于显…...

使用 Flask 实现异步请求处理
文章目录 为什么需要异步请求处理?在 Flask 中实现异步请求处理使用 Flask-Cors 扩展 总结 在开发 Web 应用程序时,异步请求处理是提高性能和并发能力的重要方法之一。Flask 是一个轻量级的 Web 框架,它提供了易于使用的工具来实现异步请求处…...

关于c++的通过cin.get()维持黑框的思考
1.前言 由于本科没有学过c语言,研究生阶段接触c上手有点困难,今天遇到关于通过cin.get()来让黑框维持的原因。 2.思考 cin.get()维持黑框不消失的原因一言蔽之就是等待输入。等待键盘的输入内容并回车(一般是回车)后cin.get()才…...

fastadmin接口输出图片 自动拼接网站URL
先自定义常量 1.文件接口路径 修改核心文件 application\common\controller\Api.php/*** 构造方法* access public* param Request $request Request 对象*/public function __construct(Request $request null){$this->request is_null($request) ? Request::instance…...

VMware Workstation 不可恢复错误:(vmui) 错误代码0xc0000094
软件版本 vmware 17 错误情况 VMware Workstation 不可恢复错误:(vmui) Exception 0xc0000094 has occurred. 问题原因 VMware升级到17.0后,将虚拟机环境的【硬件兼容性】升级至Workstation 17.X后,无法修改设备参数。 解决办法 打开需…...

DockerNetwork
Docker Network Docker Network 是 Docker 引擎提供的一种功能,用于管理 Docker 容器之间以及容器与外部网络之间的网络通信。它允许用户定义和配置容器的网络环境,以便容器之间可以相互通信,并与外部网络进行连接。 Docker Network 提供了以…...

QT学习(20):QStyle类
Qt包含一组QStyle子类,这些子类(QWindowsStyle,QMacStyle等)模拟Qt支持的不同平台的样式,默认情况下,这些样式内置在Qt GUI模块中,样式也可以作为插件提供。 Qt的内置widgets使用QStyle来执行几…...

hadoop学习之MapReduce案例:输出每个班级中的成绩前三名的学生
hadoop学习之MapReduce案例:输出每个班级中的成绩前三名的学生 所要处理的数据案例: 1500100001 施笑槐,22,女,文科六班,406 1500100002 吕金鹏,24,男,文科六班,440 1500100003 单乐蕊,22,女,理科六班,359 1500100004 葛德曜,24,男,理科三班,421 15001…...

【亲测,安卓版】快速将网页网址打包成安卓app,一键将网页打包成app,免安装纯绿色版本,快速将网页网址打包成安卓apk
背景:部分客户需求将自己网站打包成app,供用户在浏览器安装使用、 网页网址快速生成app 准备材料操作流程第一步:打开HBuilder X新建项目第二步创建Wap2App项目第三步修改App图标第四步发布app第五步查看apk 准备材料 1.需要打包的网页 2.ap…...

学习thinkphp的循环标签
1.FOREACH标签 foreach标签的用法和PHP语法非常接近,用于循环输出数组或者对象的属性,用法如下: $list User::all(); View::assign(list,$list); 模板文件中可以这样输出 {foreach $list as $key>$vo } {$vo.id}:{$vo.name} {/foreac…...

根据标签名递归读取xml字符串中element
工具类: /*** 根据标签名递归读取xml字符串中element* 例:* String xml * "<req>\n" * "<tag1></tag1>\n" * "<tag2>\n" * " <tag4></tag4>\n" * "</tag2>\n&…...

Ovid医学库文献如何在家查找下载
今天讲的数据库是一个知名医学库——Ovid Ovid隶属于威科集团的健康出版事业集团,与LWW、Adis等公司属于姊妹公司。Ovid数据库在医学外文文献数据库方面占据绝对地位,目前已有包涵人文、科技等多领域数据库300个,其中80多个是生物医学数据库…...

在已创建的git工程中添加.gitignore
有些代码创建git时,为了方便将所有文件都加入了git管理,但实际有些库的Makefile文件和编译目录的文件不需要加入管理,否则每次提交或编译后,git diff将看到非常多的冗余信息。而我们修改的核心代码都淹没在这些大量无用的信息里面…...

MR混合现实情景实训教学系统在临床医学课堂上的应用
MR混合现实情景实训教学系统在临床医学课堂上的应用可以带来许多积极的影响,具体表现在以下几个方面: 1. 增强教学的真实感和互动性:MR混合现实技术能够创建出高度逼真的模拟临床环境,使学生能够身临其境地体验临床实践。这种技术…...

就说说开一家公司的流程和成本
本人在进互联网公司和外企前,也和一位老板合作做,在一家小微公司里做过技术负责人,所以也了解开办一家公司的流程以及公司运作的成本。 通过本文大家其实能看到创业的难度。具体来讲,开办并维持着一家公司,其实需要操…...

【前端】面试八股文——数组扁平化的实现
【前端】面试八股文——数组扁平化的实现 数组扁平化是指将一个多维数组转换为一维数组。在前端开发中,处理这样的数组结构是很常见的需求。本文将详细介绍几种实现数组扁平化的方法,以帮助读者更好地理解和应用这些技术。 1. 使用 Array.prototype.fl…...