设计模式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可以直接运行。

如果觉得本文还不错,就请点个赞吧!如果有建议,也请评论指教和讨论!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux信号:信号的概念及意义

目录 一、什么是信号 kill-l查看信号 二、信号的产生 2.1系统调用 kill raise abort 2.2软件条件 13)SIGPIPE pipe信号 14&#xff09;SIGAKARM alarm信号 2.2硬件中断 2.3异常 8)SIGFPE 除0异常 11)SIGSEGV 野指针 2.4信号处理的常见方式 三、Core Dump和term…

一文详解SaaS增长模式:PLG、MLG、SLG哪种更适合你?

在SaaS&#xff08;软件即服务&#xff09;的领域中&#xff0c;增长策略的选择对于企业的成功至关重要。其中&#xff0c;PLG&#xff08;产品驱动增长&#xff09;、MLG&#xff08;市场驱动增长&#xff09;和SLG&#xff08;销售驱动增长&#xff09;是三种常见的策略&…

Centos 7 安装刻录至服务器

前言 在日常测试中&#xff0c;会遇到很多安装的场景&#xff0c;今天给大家讲一下centos 7 的安装&#xff0c;希望对大家有所帮助。 一.下载镜像 地址如下&#xff1a; centos官方镜像下载地址https://www.centos.org/download/ 按照需求依次点击下载 二.镜像刻录 镜像刻…

强悍!轻量级 Viedo Download 项目!!【送源码】

今天给大家分享一个非常轻量实用的命令行视频下载项目&#xff1a;Lux。 项目简介 Lux是一款基于Golang编写的快速、简单的视频下载库和命令行工具&#xff0c;支持众多个流行的视频网站&#xff0c;包括 YouTube、Bilibili、优酷、爱奇艺、腾讯视频、抖音快手等。 界面简洁易…

重生之 SpringBoot3 入门保姆级学习(07、整合 Redis 案例)

重生之 SpringBoot3 入门保姆级学习&#xff08;07、整合 Redis 案例&#xff09; 导入 Maven 依赖并刷新 Maven <dependencies><!--springboot3 Web 依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring…

高效至臻,Media Encoder 2024 for Mac——您的专业媒体处理首选

Media Encoder 2024 for Mac是一款专为Mac用户打造的专业视频和音频编码工具&#xff0c;凭借其卓越的编码能力和智能编辑功能&#xff0c;为用户提供了前所未有的媒体处理体验。无论是高清、4K还是8K的视频文件&#xff0c;Media Encoder 2024都能轻松驾驭&#xff0c;确保在压…

学习javascript的函数

1.什么是函数&#xff1f; 可以重复被使用的代码块 作用&#xff1a;函数可以把具有相同或者相似逻辑的代码“包裹起来”&#xff0c;有利于代码的复用。 2.函数的基本使用 1.定义函数 利用关键字Function 定义函数&#xff08;声明函数&#xff09; function 函数名(){函…

4、xss-labs之level4、lecel5

一、level4 1、测试分析 level4跟之前的3一样的思路&#xff0c;闭合value的值&#xff0c;但是通过双引号闭合&#xff0c;然后使用onclick的属性弹窗绕过 输入3的payload&#xff1a; 2、所以构造payload payload&#xff1a;"οnclickalert(1)// 二、level5 1、测…

uniapp高校二手书交易商城回收系统 微信小程序python+java+node.js+php

每年因为有大量的学生在接受教育&#xff0c;每到大学毕业季的时候&#xff0c;所使用的大量书籍对他们自己来说&#xff0c;很多是没有用&#xff0c;同时由于书籍多和不方便携带&#xff0c;导致很多大学生在毕业时将教材直接丢弃是在校大学生处理已用教材的一种主要方式。然…

数据结构-二叉树系统性学习(四万字精讲拿捏)

前言 这里我会从二叉树的概念开始讲解&#xff0c;其次涉及到概念结构&#xff0c;以及堆的实现和堆排序。 目的是&#xff0c;堆比二叉树简单&#xff0c;同时堆本质上是二叉树的其中一种情况&#xff0c;堆属于二叉树顺序结构的实现 最后完善二叉树的讲解&#xff0c;也就是…

Java与Gradle 的版本兼容性矩阵验证

1.下面这个表格显示了java和gradle的版本兼容性情况 2.根据上面这份表格理解&#xff0c;是不是java17就需要gradle 7.3之后来支持。用android studio 来试验一下: jdk选择: build成功: 说明JDK17并不是一定需要Gradle 7.3之后版本 3.使用JDK1.8、JDK11验证一下Grade 7.2是否可…

四款开源电子表格组件,轻松集成到你的项目

hello&#xff0c;大家好&#xff0c;我是徐小夕。之前和大家分享了很多可视化&#xff0c;零代码和前端工程化的最佳实践&#xff0c;最近在研究在线电子表格的技术实现&#xff0c;发现了几个优质的开源电子表格项目&#xff0c;这里和大家一起分享一下。 同时我也把其中一款…

太速科技-基于FPGA Spartan6 的双路光纤PCIe采集卡(2路光纤卡)

基于FPGA Spartan6 的双路光纤PCIe采集卡(2路光纤卡) 1、板卡概述   板卡采用xilinx Spartan6系列芯片&#xff0c;支持 PCI Express Base Specification 1.1 x1。内含丰富的逻辑资源和存储单元&#xff0c;板卡FPGA外接双片32M*16bit DDR2缓存器&#xff0c;支持乒乓操作。…

超好用的AI插件—Fitten code【IDEA 和 VScode 安装】

Fitten code安装 Fitten code是什么IDEA从磁盘安装Fitten codeVScode安装Fitten code Fitten code是什么 这是Fitten code官网&#xff0c;功能还是很多的&#xff0c;包括代码自动补全、自动添加注释、智能bug查找等等&#xff1a; Fitten Code是由非十大模型驱动的AI编程助手…

视频号小店应该怎么操作呢?不了解的小伙伴快来看!

大家好&#xff0c;我是电商小V 普通人想利用视频号小店赚钱&#xff0c;奈何自己不会直播&#xff0c;不会拍视频&#xff0c;那么普通人应该怎么在视频号中赚钱呢&#xff1f;今天咱们就来详细的说一下&#xff0c; 其实不直播&#xff0c;不拍视频也是可以在视频号上面卖货赚…

Microsoft Remote Desktop for Mac:你的跨平台远程连接利器

Microsoft Remote Desktop for Mac是一款专为Mac用户设计的远程桌面连接工具&#xff0c;它凭借卓越的性能和多项实用功能&#xff0c;成为了跨平台远程协作的首选工具。 多平台支持&#xff1a;Microsoft Remote Desktop for Mac不仅支持与其他Mac设备进行连接&#xff0c;还…

Linux入侵应急响应与排查

入侵者在入侵成功后&#xff0c;往往会留下后门以便再次访问被入侵的系统&#xff0c; 而创建系统账号是一种比较常见的后门方式。 查询特权用户特权用户(uid 为0) awk -F: $30{print $1} /etc/passwd 查找远程可以登录的账户 awk /\$1|\$5|\$6/{print $1} /etc/shadow $1&a…

Less语言

Less是一门预编译语言&#xff0c;它扩展了CSS语言&#xff0c;增加了变量、Mixin、函数等特性&#xff0c;使CSS更易维护和扩展 Less也扩充了CSS语言&#xff0c;增加了诸如变量、混合运算、函数等功能。Less既可以运行在服务端(Node.js和Rhino平台)也可以运行在客户端(浏览器…

前端面试项目细节重难点(已工作|做分享)

面试官提问&#xff1a;需求场景&#xff1a;页面上有一个单选框&#xff0c;有是否两个选项&#xff1a;当用户选择是&#xff0c;出现一个输入框&#xff0c;用户可以输入内容&#xff0c;给后端的保存接口传入参数radio和content这两个字段&#xff0c;值分别是用户选项和输…

数据集005:螺丝螺母目标检测数据集(含数据集下载链接)

数据集简介 背景干净的目标检测数据集。 里面仅仅包含螺丝和螺母两种类别的目标&#xff0c;背景为干净的培养皿。图片数量约420张&#xff0c;train.txt 文件描述每个图片中的目标&#xff0c;label_list 文件描述类别 另附一个验证集合&#xff0c;有10张图片&#xff0c;e…