当前位置: 首页 > 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…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...