当前位置: 首页 > news >正文

享元模式flyweight

  • 享元模式属于结构型模式。

  • 享元模式是池技术的重要实现方式,它可以减少重复对象的创建,使用缓存来共享对象,从而降低内存的使用。

  • 细粒度的对象其状态可以分为两种:内部状态和外部状态。

应用场景
  • 系统存在大量相似或相同的对象。

  • 外部状态相同类似情况下。

  • 需要缓冲池时。

下面将由一个例子讲解享元模式的创建和使用:

假设我们有一个系统需要实现图形的绘制,通过形状划分,所有图形都可以实现绘制颜色的功能。这里形状是图形的内部状态,颜色是图形的外部状态,内部状态是不受外界条件影响而改变。

如果我要绘制白色的圆形,黑色的方形,红色的圆形,这个时候就可以使用享元模式,圆形共享一个对象,方形共享一个对象。

角色说明:
  • Flyweight --> IShape(抽象享元角色):接口或抽象类,可以同时定义出对象的外部状态和内部状态的接口或实现。

  • ConcreteFlyweight --> Circle,Rectangle(具体享元角色):实现抽象享元角色中定义的业务。

  • FlyweightFactory --> ShapeFactory(享元工厂):管理对象池和创建享元对象。

定义图形接口:

public interface IShape {void draw(String color);
}

圆形实现接口,实现圆形的绘制方法:

public class Circle implements IShape {String mShapeName = "圆形";@Overridepublic void draw(String color) {System.out.println("绘制" + mShapeName + ": " + color);}
}

方形实现接口,实现方形的绘制方法:

public class Rectangle implements IShape {String mShapeName = "方形";@Overridepublic void draw(String color) {System.out.println("绘制" + mShapeName + ": " + color);}
}

定义一个工厂类,创建缓存池和对应图形对象:

public class ShapeFactory {private Map<String, IShape> mShapeMap = new HashMap<>();public IShape getShape(Class<?> clazz) {IShape iShape = mShapeMap.get(clazz.getCanonicalName());if (iShape == null) {if (clazz == Circle.class) {System.out.println("创建Circle...");iShape = new Circle();} else if (clazz == Rectangle.class) {System.out.println("创建Rectangle...");iShape = new Rectangle();}mShapeMap.put(clazz.getCanonicalName(), iShape);}return iShape;}
}

具体调用:

public class TestMain {public static void main(String[] args) {ShapeFactory factory = new ShapeFactory();IShape circle = factory.getShape(Circle.class);circle.draw("white");IShape rectangle = factory.getShape(Rectangle.class);rectangle.draw("black");IShape circle2 = factory.getShape(Circle.class);circle2.draw("red");System.out.println("circle:" + circle.hashCode() + " rectangle:" + rectangle.hashCode() + " circle2:" + circle2.hashCode());}
}

可以看到circle和circle2的hashCode一致,说明他们指向了同一块内存空间,而rectangle是单独的hashCode。

其实还有一个例子也可以设计成享元模式:黑白棋。这个大家可以自己理解下~

优点:
  • 有共用数据不想多次创建时,可以实现对象共享,减少内存开销。

缺点:
  • 设计复杂,要区分内部状态和外部状态

Android中的享元模式:
  • String类:

String s1 = "abc";
String s2 = "abc";print(s1 == s2)  //这里s1和s2指向同一个引用,打印true
思考:

其实写到这里我有了一个疑问,享元模式是不是就是单例模式+工厂模式?

欢迎大家赐教~

相关文章:

享元模式flyweight

享元模式属于结构型模式。享元模式是池技术的重要实现方式&#xff0c;它可以减少重复对象的创建&#xff0c;使用缓存来共享对象&#xff0c;从而降低内存的使用。细粒度的对象其状态可以分为两种&#xff1a;内部状态和外部状态。应用场景系统存在大量相似或相同的对象。外部…...

Pulsar

一、简介Apache Pulsar是Apache软件基金会顶级项目&#xff0c;是下一代云原生分布式消息流平台&#xff0c;集消息、存储、轻量化函数式计算为一体&#xff0c;采用计算与存储分离架构设计&#xff0c;支持多租户、持久化存储、多机房跨区域数据复制&#xff0c;具有强一致性、…...

项目介绍 + 定长内存池设计及实现

你好&#xff0c;我是安然无虞。 文章目录项目介绍当前项目做的是什么?技术栈内存池是什么?池化技术内存池内存池主要解决的问题malloc定长内存池学习目的定长内存池设计项目介绍 当前项目做的是什么? 这个项目是实现一个高并发的内存池, 它的原型是 Google 的一个开源项…...

Linux--线程安全的单例模式--自旋锁--0211

1. 线程安全的单例模式 1.1 什么是单例模式 某些类, 只应该具有一个对象(实例), 就称之为单例. 1.1.1 懒汉方式实现单例模式 以上篇博文的线程池为例 Liunx--线程池的实现--0208 09_Gosolo&#xff01;的博客-CSDN博客 实现懒汉模式首先要先将构造函数私有化&#xff0c;…...

图文解说S参数(进阶篇)

S参数是RF工程师/SI工程师必须掌握的内容&#xff0c;业界已有多位大师写过关于S参数的文章&#xff0c;即便如此&#xff0c;在相关领域打滚多年的人&#xff0c; 可能还是会被一些问题困扰着。你懂S参数吗? 图文解说S参数&#xff08;基础篇&#xff09; 请继续往下看...台湾…...

Sentinel源码阅读

基础介绍 Sentinel 的使用可以分为两个部分: 核心库&#xff08;Java 客户端&#xff09;&#xff1a;不依赖任何框架/库&#xff0c;能够运行于 Java 8 及以上的版本的运行时环境&#xff0c;同时对 Dubbo / Spring Cloud 等框架也有较好的支持&#xff08;见 主流框架适配&…...

2023年浙江食品安全管理员考试真题题库及答案

百分百题库提供食品安全管理员考试试题、食品安全管理员考试预测题、食品安全管理员考试真题、食品安全管理员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 一、判断题 7.&#xff08;重点&#xff09;《餐饮服务食品安全…...

Webstorm 代码没有提示,uniapp 标签报错

问题 项目是用脚手架创建的&#xff1a; vue create -p dcloudio/uni-preset-vue my-project 打开之后&#xff0c;添加view标签警告报错的。代码也没有提示&#xff0c;按官方说法&#xff1a;CLI 工程默认带了 uni-app 语法提示和 5App 语法提示。 但是我这里就是有问题。…...

MySQL-Innodb引擎事务原理

文章目录1.事务介绍2 事务特性3. 事务的实现原理4 redo log 保证持久性5 undo log 保证原子性6 MVCC 概念6.1 隐藏字段6.2 版本链6.3 ReadView6.3.1readview 版本控制规则7 隔离性 实现7.2 隔离性- REPEATABLE READ 可重复读下8 一致性1.事务介绍 事务是一组操作的集合&#xf…...

Linux操作系统学习(了解环境变量)

文章目录环境变量初识除了上述介绍的PATH&#xff0c;还有一些常见的环境变量如&#xff1a;查看环境变量方法 &#xff1a;环境变量的基本概念&#xff1a;本地变量&#xff1a;环境变量初识 环境变量解释起来比较抽象&#xff0c;先看示例&#xff1a; #include <stdio.…...

数据分析思维(六)|循环/闭环思维

循环/闭环思维 1、概念 在很多的分析场景下&#xff0c;我们需要按照一套流程反复分析&#xff0c;而不是进行一次性的分析&#xff0c;也就是说这套流程的结果会成为该流程的新一次输入&#xff0c;从而形成一个闭环&#xff0c;此时的分析思维我们称之为循环/闭环思维。 常…...

C++:类和对象(下)

文章目录1 再谈构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字2 static成员2.1 概念2.2 特性3 友元3.1 友元函数&#xff08;流插入&#xff08;<<&#xff09;及流提取&#xff08;>>&#xff09;运算符重载&#xff09;3.2 友元类4 内部类5 匿名对…...

ASP.NET Core MVC 项目 AOP之IResultFilter和IAsyncResultFilter

目录 一:说明 二:IActionFilter同步 三:IAsyncActionFilter异步 一:说明 IResultFilter同步过滤器与IAsyncResultFilter异步过滤器常常被用作于渲染视图或处理结果。 IResultFilter同步过滤器执行顺序: 1:执行控制器中的构造函数,实例化控制器 2:执行具体的Acti…...

jstack排查cpu占用高[复习]

这样就可以看到占用CPU高的代码位置。 总结&#xff1a;就是先查到占用高的应用和具体的线程&#xff0c;然后根据线程到堆积信息查找即可。 不过堆栈信息非十进制&#xff0c;需提前把线程号转为十六进制。 这样就可以看到占用CPU高的代码位置。 总结&#xff1a;就是先查到…...

网络安全-Pyhton环境搭建

网络安全-Pyhton环境搭建 https://www.kali.org/get-kali/#kali-installer-images—kali官网下载地址 python这个东东呢 是目前来说最简单&#xff0c;方便的开源的脚本语言 广泛用于Web开发&#xff0c;AI&#xff0c;网站开发等领域 python要装2和3 为什么要安装两个版本…...

SpringBoot Mybatis 分页实战

pageInfo的属性 pageNum&#xff1a;当前页 pageSize&#xff1a;页面数据量 startRow&#xff1a;当前页首条数据为总数据的第几条 endRow&#xff1a;当前页最后一条数据为总数据的第几条 total&#xff1a;总数据量 pages&#xff1a;总页面数 listPage{}结果集 reasonable …...

计算机断层扫描结肠镜和全自动骨密度仪在一次检查中的可行性

计算机断层扫描结肠镜和全自动骨密度仪在一次检查中的可行性 Feasibility of Simultaneous Computed Tomographic Colonography and Fully Automated Bone Mineral Densitometry in a Single Examination 简单总结&#xff1a; 数据&#xff1a;患者的结肠镜检查和腹部CT检查…...

Java多级缓存是为了解决什么的?

前言   提到缓存&#xff0c;想必每一位软件工程师都不陌生&#xff0c;它是目前架构设计中提高性能最直接的方式。   缓存技术存在于应用场景的方方面面。从网站提高性能的角度分析&#xff0c;缓存可以放在浏览器&#xff0c;可以放在反向代理服务器&#xff0c;还可以放…...

MongoDB--》索引的了解及具体操作

目录 索引—index 索引的类型 索引的管理操作 索引的使用 索引—index 使用索引的原因&#xff1a;索引支持在MongoDB中高效地执行查询。如果没有索引&#xff0c;MongoDB必须执行全集合扫描&#xff0c;即扫描集合中的每个文档&#xff0c;以选择与查询语句匹配的文档。这…...

Python open()函数详解:打开指定文件

在 Python 中&#xff0c;如果想要操作文件&#xff0c;首先需要创建或者打开指定的文件&#xff0c;并创建一个文件对象&#xff0c;而这些工作可以通过内置的 open() 函数实现。open() 函数用于创建或打开指定文件&#xff0c;该函数的常用语法格式如下&#xff1a;file ope…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...