Android设计模式--享元模式

水不激不跃,人不激不奋

一,定义

使用共享对象可有效地支持大量的细粒度的对象

享元模式是对象池的一种实现,用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,来缓存可共享的对象,达到对象共享,避免创建过多对象的效果,这样一来就可以提升性能,避免内存溢出等。

在享元模式中会建立一个对象容器,在经典的享元模式中该容器为一个Map,它的键是享元对象的内部状态,它的值就是享元对象本身。客户端程序通过这个内部状态从享元工厂中获取享元对象,如果有缓存,则使用缓存对象,否则创建一个享元对象并且存入容器中,这样一来就避免了创建过多对象的问题。

二,使用场景

1,系统中存在大量的相似对象

2,细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,就是说对象没有特定身份

3,需要缓冲池的场景

三,角色介绍

Flyweight:享元对象抽象基类或接口

ConcreteFlyweight:具体的享元对象

FlyweightFactory:享元工厂,负责管理享元对象池和创建享元对象

四,使用案例

假设在吃鸡游戏中,每局游戏都会有100个玩家参与游戏,所以每局游戏都会创建100个玩家角色,如果一个玩家进行了10局游戏,他的角色就会被创建10次。这样就会造成频繁的GC,从而影响性能。如果我们使用享元模式,将玩家的姓名作为key,玩家角色作为value存放在内存中,这样就不会频繁的去创建玩家角色,避免造成不必要的资源浪费。

首先,创建一个玩家角色接口作为享元对象抽象接口,该接口定义玩家自己选择皮肤玩游戏:

public interface Player {/*** 玩游戏* @param skin 自己选择的皮肤* */void playGame(String skin);
}

然后创建具体的享元对象 :

public class ConcretePlayer implements Player{private String name;public ConcretePlayer(String name) {this.name = name;}@Overridepublic void playGame(String skin) {System.out.println("玩家"+name+"使用"+skin+"角色玩游戏");}
}

最后创建享元工厂:

public class PlayerFactory {private static HashMap<String,Player> map =new HashMap<>();public static Player createPlayer(String name){if(map.get(name)==null){System.out.println("创建新的角色");ConcretePlayer concretePlayer =new ConcretePlayer(name);map.put(name,concretePlayer);return concretePlayer;}else {System.out.println("从缓存中拿取角色");ConcretePlayer player = (ConcretePlayer) map.get(name);return player;}}
}

使用:

Player player = PlayerFactory.createPlayer("N港之王");
player.playGame("红螳螂");
Player player1 = PlayerFactory.createPlayer("N港之王");
player1.playGame("黄螳螂");
Player player2 = PlayerFactory.createPlayer("N港之王");
player2.playGame("紫螳螂");

输出:

这样,即使玩家使用同一角色玩了好多把游戏,都只创建了一次角色,其余的都是从缓存中获取的

五,总结

享元模式实现比较简单,但是它的作用在某些场景确实及其重要。它可以大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能,但它同时也提高了系统的复杂性,需要分离出外部状态和内部状态,而且外部状态具有固化特性,不应该随内部状态改变而改变,否则导致系统的逻辑混乱。

享元模式的优点在于它大幅度地降低内存中对象的数量,但是,它做到这一点所付出的代价也是很高的。

享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

参考文献:Android源码设计模式解析与实战

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

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

相关文章

Qt项目打包发布超详细教程

https://blog.csdn.net/qq_45491628/article/details/129091320

HTML网站稳定性状态监控平台源码

这是一款网站稳定性状态监控平台源码&#xff0c;它基于UptimeRobot接口进行开发。当您的网站遇到故障时&#xff0c;该平台能够通过邮件或短信通知您。下面是对安装过程的详细说明&#xff1a; 安装步骤 将源码上传至您的主机或服务器&#xff0c;并进行解压操作。 在Uptim…

自动化测试中几种常见验证码的处理方式及如何实现?

UI自动化测试时&#xff0c;需要对验证码进行识别处理&#xff0c;有很多方式&#xff0c;每种方式都有自己的特点&#xff0c;以下是一些常用处理方法&#xff0c;仅供参考。 1 去掉验证码 从自动化的本质上来讲&#xff0c;主要是提升测试效率等&#xff0c;但是为了去研究验…

【点云surface】 修剪B样条曲线拟合

1 介绍 Fitting trimmed B-splines&#xff08;修剪B样条曲线拟合&#xff09;是一种用于对给定的点云数据进行曲线拟合的算法。该算法使用B样条曲线模型来逼近给定的点云数据&#xff0c;并通过对模型进行修剪来提高拟合的精度和准确性。 B样条曲线是一种常用的曲线表示方法…

【element优化经验】el-dialog修改title样式

目录 前言 解决之路 1.把默认的这个图标隐藏&#xff0c;官方的api有这个属性&#xff1a;showClose值设置false. 2.title插槽定制&#xff1a;左边定制标题&#xff0c;右边定制按钮区域。 3.背景颜色修改&#xff1a;默认title是有padding的需要把它重写调&#xff0c;然…

基于 STM32Cube.AI 的嵌入式人脸识别算法实现

本文介绍了如何使用 STM32Cube.AI 工具开发嵌入式人脸识别算法。首先&#xff0c;我们将简要介绍 STM32Cube.AI 工具和 STM32F系列单片机的特点。接下来&#xff0c;我们将详细讨论如何使用 STM32Cube.AI 工具链和相关库来进行人脸识别算法的开发和优化。最后&#xff0c;我们提…

Netty实现websocket且实现url传参的两种方式(源码分析)

1、先构建基本的netty框架 再下面的代码中我构建了一个最基本的netty实现websocket的框架&#xff0c;其他个性化部分再自行添加。 Slf4j public class TeacherServer {public void teacherStart(int port) throws InterruptedException {NioEventLoopGroup boss new NioEve…

Day40力扣打卡

打卡记录 包子凑数&#xff08;裴蜀定理 DP&#xff09; 根据裴蜀定理&#xff0c;存在 c gcd(a, b) 使不定方程ax by c满足条件&#xff0c;如果gcd(a, b) 1即a与b互素的情况下&#xff0c;就会 ax by 1&#xff0c;由于为1可以构造后面的无穷数字&#xff0c;故得到结…

Centos7 离线安装 CDH7.1.7

1. 安装CDH的准备工作&#xff08;所有节点都要执行&#xff09; 1.1 准备环境 角色 IP k8s-master 192.168.181.129 k8s-node1 192.168.181.130 k8s-node2 192.168.181.131 1.2 安装JDK # https://www.oracle.com/java/technologies/downloads/#java11 wget rpm -ivh…

亚马逊Listing怎么写!亲身经验分享

亚马逊运营的重要环节之一&#xff0c;listing的攥写&#xff0c;可以决定了产品的搜索排名&#xff0c;用户的点击率和转化率&#xff0c;那么如果你的产品排名或者转化不理想的情况&#xff0c;可以考虑对listing进行优化&#xff0c;在关键词过多和语句流程通顺的情况下&…

js获取时间日期

目录 Date 对象 1. 获取当前时间 2. 获取特定日期时间 Date 对象的方法 1. 获取各种日期时间组件 2. 获取星期几 3. 获取时间戳 格式化日期时间 1. 使用 toLocaleString() 方法 2. 使用第三方库 UNIX 时间戳 内部表示 时区 Date 对象 JavaScript中内置的 Date 对象…

数据挖掘之PCA-主成分分析

PCA的用处&#xff1a;找出反应数据中最大变差的投影&#xff08;就是拉的最开&#xff09;。 在减少需要分析的指标同时&#xff0c;尽量减少原指标包含信息的损失&#xff0c;以达到对所收集数据进行全面分析的目的 但是什么时候信息保留的最多呢&#xff1f;具体一点&#…

​飞凌嵌入式FCU2601网关,为工商业储能EMS注入智慧的力量

一、火热的储能行业&#xff0c;寻求新的市场机会 最近一段时间以来&#xff0c;世界储能大会、上海储能展、能源电子产业发展大会等多个储能相关论坛和展览密集登场&#xff0c;即使“内卷”已成为了业内讨论的热词&#xff0c;但寻求新的市场机会仍然是行业共识&#xff0c;…

Qt C++中调用python,并将软件打包发布,python含第三方依赖

工作中遇到qt c调用我的python 代码&#xff0c;并且想要一键打包&#xff0c;这里我根据参考的以及个人实践的结果来简单实现一下。 环境&#xff1a;windows系统&#xff0c;QT Creater 4.5&#xff0c; python 3.8&#xff08;anaconda虚拟环境&#xff09; 1. 简单QT调用…

electron windows robotjs 安装教程

Robotjs 安装 前言第一步 : 安装python第二步 : 安装Visual Studio 2022第三步 : 安装robotjs 前言 robotjs可以控制鼠标键盘&#xff0c;获取屏幕内容&#xff0c;配合electron可做很多自动化操作。windows下配置环境有很多坑&#xff0c;很多文章都太旧了。试了很多次发现了…

ky10 server x86 auditd安装(日志审计系统)

概述 Auditd工具可以帮助运维人员审计Linux&#xff0c;分析发生在系统中的发生的事情。Linux 内核有用日志记录事件的能力&#xff0c;包括记录系统调用和文件访问。管理员可以检查这些日志&#xff0c;确定是否存在安全漏洞&#xff08;如多次失败的登录尝试&#xff0c;或者…

golang学习笔记——接口和继承比较2

接口和继承 现在有一个需要要求大学生和足球运动员掌握英语技能&#xff0c;请问怎么实现? 给运动员和学生结构体添加studyEnglish方法显示是可以的&#xff0c;但是篮球动员和中学生也学习了英语&#xff0c;显示不行。这时&#xff0c;我们可以直接给足球运动员和大学生添加…

跳转应用市场详情页market

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、跳转到各大厂商应…

播放器开发(四):多线程解复用与解码模块实现

学习课题&#xff1a;逐步构建开发播放器【QT5 FFmpeg6 SDL2】 前言 根据第一章内容&#xff0c;我们首先可以先把解复用和解码模块完成&#xff0c;其中需要使用到多线程以及队列&#xff0c;还需要使用FFmpeg进行解复用和解码动作的实现。 创建BaseQueue基类 BaseQueue.h…

亚马逊两步验证有哪些验证方法?

亚马逊通常提供多种两步验证的方式&#xff0c;包括短信&#xff08;通过手机接收验证码&#xff09;和认证器应用程序&#xff08;如Google Authenticator、Authy等&#xff09;。选择你偏好的方式。 短信验证&#xff1a; 如果选择短信验证&#xff0c;需要将你的手机号码关联…