设计模式:享元模式

设计模式:享元模式

在这里插入图片描述

什么是享元模式

首先我们需要简单了解一下什么是享元模式。享元模式(Flyweight Pattern):主要用于减少创建对象的数量,以减少内存占用和提高性能。享元模式的重点就在这个享字,通过一些共享技术来减少对象的创建,实际上Java中String值的存储,Volley中的ByteArrayPool也使用到了享元模式,这对提高性能很有用。

感觉目前大部分的缓存机制都会用到享元模式。

享元模式结构图

享元模式在一般情况下可以分成四个部分,也可以大体分为两部分,分别是享元工厂类,享元(抽象)类。如果学习过池有关的概念的话,我们就可以把享元工厂类看做是一个池(Pool),享元类看做是池中的数据。

标准享元模式的结构图:
在这里插入图片描述

可以看到除了共享的享元类之外还有一类不参与共享的享元类,因为享元模式只是使共享成为可能而不强制共享。

享元模式工作的一般流程

享元模式工作的流程和缓存机制很像(或许应该说缓存机制和它很像吗),当我们需要获取一个享元对象时享元工厂会检查其存储空间中是否已经有所需要的享元实例,如果有就将它直接返回,如果没有就创建一个并加入到享元工厂的存储空间中去。

享元模式的简单实现(Kotlin)

首先我们直接定义一个享元类:

class flyweight(val id:Int) {var message = "empty body"fun execute(){println(message)}
}

这里我们就不定义接口什么的了,直接创建一个简单的例子。这是一个享元类,它有两个参数,分别是id和message。id值是每个享元类唯一确定的一个值,相当于数据库中的主键,我们想要通过这个值来判断这个享元类是否是我们想要的实例。message对象和享元类的具体执行有关。

接着我们定义一个工厂类:

class flyweightFactory{val Pool = HashMap<Int,flyweight>()fun getFlyweight(id: Int,msg:String):flyweight{if (!Pool.containsKey(id)){ //如果没有找到对应的实例就新创建一个val newInstance = flyweight(id)Pool.put(id,newInstance)}return Pool.get(id)?.apply {message = msg}!!}}

这个类的逻辑很简单,它内部有一个Pool变量来存储享元对象。还有一个getFlyweight方法用于获取它内部管理的享元对象,该方法有两个参数,第一个参数即为我们想要获得的享元实例的id,这是用于判断我们想要的享元实例是否存在,第二个参数将会被赋予给最后返回的享元对象的message中,用来影响享元对象的execute方法的执行结果。

内部状态和外部状态

内部状态和外部状态的概念干讲比较抽象,所以我们给完上面的简单例子之后结合来讲。首先我们联系享元模式的使用场景,其中之一就是拥有众多重复内容的对象,比如说一个ppt模板,对于ppt来说可能大部分的结构都是一致的,不变的只有上面显示的文字。这种情况下如果把ppt抽象成一个类的话,我们就可以共享它的模板,这个模板属于这个类内部的,我们称之为内部状态,一般内部状态是不会被外部调用给更改的。而ppt需要显示的文字就属于是外部状态,它取决于外部调用传入的参数。

我们可以对照上面的例子,其中显然flyweight类的id参数为内部参数,因为它一旦形成是不随外部传入的参数而改变的,这也可以看做是我们共享的东西。再抽象一点,这个execute方法也是内部状态,因为它的逻辑也不随外部参数而改变。而其中哪个message参数就是外部状态,因为它每次都会随着外部传入的参数而改变。

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

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

相关文章

java---jar详解

一、help C:\Users\lichf1>jar 用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ... 选项:-c 创建新档案-t 列出档案目录-x 从档案中提取指定的 (或所有) 文件-u 更新现有档案-v 在标准输出中生成详细输出-f 指定档案文件名-m…

《Web安全基础》04. 文件操作安全

web 1&#xff1a;文件操作安全2&#xff1a;文件上传漏洞2.1&#xff1a;简介2.2&#xff1a;防护与绕过2.3&#xff1a;WAF 绕过2.3.1&#xff1a;数据溢出2.3.2&#xff1a;符号变异2.3.3&#xff1a;数据截断2.3.4&#xff1a;重复数据 3&#xff1a;文件包含漏洞4&#xf…

7、Spring之依赖注入源码解析(下)

resolveDependency()实现 该方法表示,传入一个依赖描述(DependencyDescriptor),该方法会根据该依赖描述从BeanFactory中找出对应的唯一的一个Bean对象。 @Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Null…

一个最简verilog代码的分析

module testmod( input CLK, output reg [1:0]acc);always(posedge CLK)acc<acc2d1; endmodule 上述代码综合后的电路图为&#xff1a; 分析1 假设在t1时刻&#xff0c;两个触发器的状态都是1&#xff0c;即acc2b11&#xff0c;此时半加器1的A端是1&#xff0c;则D触发器1…

Postman接口压力测试 ---- Tests使用(断言)

所谓断言&#xff0c;主要用于测试返回的数据结果进行匹配判断&#xff0c;匹配成功返回PASS&#xff0c;失败返回FAIL。 下图方法一&#xff0c;直接点击右侧例子函数&#xff0c;会自动生成出现在左侧窗口脚本&#xff0c;只需修改数据即可。 方法二&#xff1a;直接自己写脚…

动态封装对象,属性来自json

需求&#xff1a; 如何动态的获取一个对象的字段&#xff0c;假如一个对象里面有name,age&#xff0c;sex三个字段&#xff0c;我想取name的值&#xff0c;这个name是存在一个json中&#xff0c;json的格式如下[{"key":"name"},{"key":"age…

使用内网端口映射方案,轻松实现U8用友ERP的本地部署异地远程访问——“cpolar内网穿透”

文章目录 前言1. 服务器本机安装U8并调试设置2. 用友U8借助cpolar实现企业远程办公2.1 在被控端电脑上&#xff0c;点击开始菜单栏&#xff0c;打开设置——系统2.2 找到远程桌面2.3 启用远程桌面 3. 安装cpolar内网穿透3.1 注册cpolar账号3.2 下载cpolar客户端 4. 获取远程桌面…

排序算法概述

1、数据排序&#xff1a; 将一个文件的记录按关键字不减&#xff08;或不增&#xff09;次序排列&#xff0c;使文件成为有序文件&#xff0c;此过程称为排序。 2、排序的稳定性&#xff1a; 稳定排序&#xff1a; 若排序后&#xff0c;相同关键字的记录保持它们原来的相对次序…

机器学习笔记之最优化理论与方法(九)无约束优化问题——常用求解方法(下)

机器学习笔记之最优化理论与方法——基于无约束优化问题的常用求解方法[下] 引言回顾&#xff1a;经典牛顿法的缺陷与拟牛顿法思想经典牛顿法缺陷与修正牛顿法拟牛顿法与矩阵 B k 1 \mathcal B_{k1} Bk1​的选择 拟牛顿法之 DFP \text{DFP} DFP方法 DFP \text{DFP} DFP迭代公式…

探索装饰艺术的未来,留存传统的精髓

近一个世纪后&#xff0c;装饰艺术终于卷土重来。正如我们在全球新的项目、室内空间和家具中所看到的&#xff0c;那种令我们渴望20世纪初20年代繁荣时期的奢华和魅力。作为装饰艺术建筑和设计的独特身份一直在世界上继续启发着人们&#xff0c;那么从新的设计和现有设计的保留…

从零基础到精通Flutter开发:一步步打造跨平台应用

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 导言 Flutter是一种流行…

【RocketMQ】消息的拉取

在上一讲中&#xff0c;介绍了消息的存储&#xff0c;生产者向Broker发送消息之后&#xff0c;数据会写入到CommitLog中&#xff0c;这一讲&#xff0c;就来看一下消费者是如何从Broker拉取消息的。 RocketMQ消息的消费以组为单位&#xff0c;有两种消费模式&#xff1a; 广播…

如何使用SQL系列 之 如何在MySQL中使用存储过程

引言 通常&#xff0c;当使用关系型数据库时&#xff0c;你直接在应用程序代码中发出单独的结构化查询语言(SQL)查询来检索或操作数据&#xff0c;如SELECT、INSERT、UPDATE或DELETE。这些语句直接作用于并操作底层数据库表。如果相同的语句或一组语句中使用多个应用程序访问同…

Element Plus table formatter函数返回html内容

查看 Element Plus table formatter 支持返回 类型为string 和 VNode对象&#xff1b; 若依全局直接用h函数&#xff0c;无需引用 下面普通基本用法&#xff1a;在Element Plus中&#xff0c;你可以使用自定义的formatter函数来返回VNode对象&#xff0c;从而实现更灵活的自定…

RabbitMQ基本概念和工作原理

目录 RabbitMQ的基本概念 RabbitMQ的工作原理 RabbitMQ的交换机类型 RabbitMQ的实现原理 RabbitMQ的消息确认机制 RabbitMQ的消息持久化机制 RabbitMQ的事务 RabbitMQ的消息分发流程 RabbitMQ的消息分发机制 RabbitMQ实现RPC的机制 RabbitMQ的基本概念 RabbitMQ是一…

uni-app vuex全局计时

功能需求&#xff0c;在A页面进入时候开始计时中间会去到B页面查看数据&#xff0c;但是并没有销毁当前页面&#xff0c;所以计时一直在&#xff0c;直到在B页面提交数据&#xff0c;才结束计时 在根文件夹创建 store文件夹&#xff0c;同时创建index.js文件import Vue from v…

Navicat连接mysql8.0:提示无法加载身份验证插件“caching_sha2_password”

Navicat连接mysql时&#xff0c;提示&#xff1a;Unable to load authentication plugin ‘caching_sha2_password‘. 原因&#xff1a;mysql 8.0 默认使用 caching_sha2_password 身份验证机制。 D:\MySQL8.0\install\bin>mysql -uroot -p123456789 #登录 mysql: [War…

《动手学深度学习 Pytorch版》 4.10 实战Kaggle比赛:预测比赛

4.10.1 下载和缓存数据集 import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)): #save"""下载一个…

【Express.js】代码规范

代码规范 编程规范&#xff0c;对于一个优秀的项目是不可或缺的&#xff0c;有了良好的代码规范&#xff0c;有益于项目的维护与拓展。 命名规范 命名的第一要义是明了&#xff0c;要让阅读者看到命名就能大概猜测出其意义或用处。 以用户身份&#xff08;userRole&#xff…

Pyramid Scene Parsing Network–CVPR,2017论文解读及其pytorch代码

文章目录 Pyramid Scene Parsing Network--CVPR&#xff0c;2017一、背景介绍二、网络结构和优化方法三、实验结果 Pyramid Scene Parsing Network–CVPR&#xff0c;2017 Github代码链接 一、背景介绍 现阶段随着数据集制作精细化、标签种类变多、具有语义相似标签等导致出…