阿里云开发者社区

电脑版
提示:原网页已由神马搜索转码, 内容由developer.aliyun.com提供.

享元模式~

2024-05-23103
版权
版权声明:
本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议》和 《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
简介:享元模式~

“享元”我们可以理解为共享元素,比如我们生活中的共享单车,共享充电宝,共享汽车,这样做的目的就是为了提高资源的复用,但对于共享的单车,充电宝等,它的拥有者和创建时间是不相同的,但是它核心的东西都是一致的,那么如果在我们的程序中有很多重复的对象,就会造成很大的内存开销。


在享元模式中,它将元素分为两种状态,一部分是内部状态,例如共享单车,这部分是可以完全被共享的,但是对于共享单车的另一部分资源,比如拥有者和创建时间,这部分信息是由客户端来决定的,谁此时使用,那么这部分的信息就是和谁有关的。


享元模式实现共享的核心是,我们不需要关心外部状态,将核心的资源包围起来共享出去,它内部信息都不会随着环境改变而改变,而外部状态,它会随着环境的改变而改变,这部分信息一定不是由我们自己来保存,共享对象一定不会保存这部分信息,这部分信息由客户端保存,客户端在用的时候,传入到享元对象内部,享元对象内部可以自己做一些处理,去使用或者展示他们,享元模式运用共享技术有效地支持大量细类度[细类度对象是指在某个类别下,具有不同属性或特征的对象,可以看作是对于一个类别的细分]的对象,享元模式最典型的应用就是池技术,比如字符串常量池,数据库连接池,线程池等等,他们都是实现了对共享元素的有效利用,避免去创建大量重复的对象,有效地利用资源。


享元对象的内部状态和环境是没有任何关系的,那么外部状态如何传入呢?方法即为我们在定义享元的时候可以定义一些方法,用于将外部状态传入,这样就实现了一个享元对象既有内部状态,也可以接受外部状态

实例:

1:创建抽象的享元对象

package com.wjr.xiangyaunModel.shared_power_bank;
abstract class PowerBankWeight {//抽象的享元对象    protected int state=0;//0表示未使用,1表示使用   abstract void getPowerBank(String username);    abstract void backPowerBank();}

2:创建具体的享元对象

package com.wjr.xiangyaunModel.shared_power_bank;
public class LvPowerBankWeight extends PowerBankWeight{    protected String id;    public LvPowerBankWeight(String id) {        this.id=id;    }
    @Override    void getPowerBank(String userName) {        state=1;//表示当前为使用状态        System.out.println(userName+"正在使用"+id+"号充电宝");
    }
    @Override    void backPowerBank() {            state=0;//表示当前为未使用状态    }}

3:创建享元对象工厂

package com.wjr.xiangyaunModel.shared_power_bank;
import java.util.HashSet;
public class PowerBankFlyWeightFactory {    private static PowerBankFlyWeightFactory powerBankFlyWeightFactory=new PowerBankFlyWeightFactory();    HashSet<LvPowerBankWeight> pool=new HashSet<>();//享元对象池--数据结构不唯一,也可选择TreeSet,如何进行选择需要我们根据需求进行分析
    public static PowerBankFlyWeightFactory getPowerBankFlyWeightFactory(){        return powerBankFlyWeightFactory;    }
    public PowerBankFlyWeightFactory() {        //表示享元对象的数量为3        for(int i=0;i<3;i++){            pool.add(new LvPowerBankWeight(i+"号"));        }    }    public  LvPowerBankWeight getPowerBank(){        for(LvPowerBankWeight lvPowerBankWeight:pool){            if(lvPowerBankWeight.state==0){                return lvPowerBankWeight;            }        }        return null;    }}
package com.wjr.xiangyaunModel.shared_power_bank;
public class FlyWeightPattern {    public static void main(String[] args) {        LvPowerBankWeight lvPowerBankWeight1=PowerBankFlyWeightFactory.getPowerBankFlyWeightFactory().getPowerBank();        lvPowerBankWeight1.getPowerBank("小学牲");        lvPowerBankWeight1.backPowerBank();
        LvPowerBankWeight lvPowerBankWeight2=PowerBankFlyWeightFactory.getPowerBankFlyWeightFactory().getPowerBank();        lvPowerBankWeight2.getPowerBank("中学牲");//        lvPowerBankWeight2.backPowerBank();
        LvPowerBankWeight lvPowerBankWeight3=PowerBankFlyWeightFactory.getPowerBankFlyWeightFactory().getPowerBank();        lvPowerBankWeight3.getPowerBank("大学牲");//        lvPowerBankWeight3.backPowerBank();
        LvPowerBankWeight lvPowerBankWeight4=PowerBankFlyWeightFactory.getPowerBankFlyWeightFactory().getPowerBank();        lvPowerBankWeight4.getPowerBank("打工人");        lvPowerBankWeight4.backPowerBank();    }}

输出如下所示:

小学牲正在使用1号号充电宝中学牲正在使用1号号充电宝大学牲正在使用2号号充电宝打工人正在使用0号号充电宝

享元模式通过池技术,可以确保内存中相同或相似的对象只保留一份,可以大大节约系统资源,提高系统的性能,享元模式的外部状态相对独立,不会影响内部状态,内外环境分离,使得享元对象可以在不同环境中被共享,因为它将状态区分出来,将外部状态由客户端指定,内部状态自己维护,这样使得它能够在不同环境中进行共享,它的缺点也很明显,因为我们要分离出内外状态,因此程序的逻辑性会比较复杂一点。外部状态都需要客户端传入,这也会影响它的运行时间。

文章标签:
相关文章
|
小程序JavaScript
【微信小程序】-- WXML 模板语法 - 数据绑定(九)
【微信小程序】-- WXML 模板语法 - 数据绑定(九)
|
10月前
|
网络安全数据安全/隐私保护
使用静态IP时出现“代理检测失败”的原因是什么?
随着数字化时代的加速发展,网络安全与隐私保护成为核心需求,HTTP凭借其独特优势成为新时代热门选择。本文分析了“代理检测失败,请确认代理IP的有效性”这一问题,主要原因包括:代理IP失效、配置错误、网络不稳定、类型不匹配及请求频率过高。解决建议为检查IP有效性、确保正确配置、选择合适代理类型并控制请求频率。希望这能帮助您解决问题!
45599
使用静态IP时出现“代理检测失败”的原因是什么?
|
安全测试技术
Fiddler入门教程全家桶,建议收藏
Fiddler入门教程全家桶,建议收藏
|
网络协议
一文彻底搞定TCP协议的三次握手和四次挥手
通过本章的探险,你将学会如何TCP协议的三次握手和四次挥手
|
11月前
|
前端开发UED开发者
React.lazy()与Suspense:实现按需加载的动态组件——深入理解代码分割、提升首屏速度和优化用户体验的关键技术
【8月更文挑战第31天】在现代Web应用中,性能优化至关重要,特别是减少首屏加载时间和提升用户交互体验。React.lazy()和Suspense组件提供了一种优雅的解决方案,允许按需加载组件,仅在需要渲染时加载相应代码块,从而加快页面展示速度。Suspense组件在组件加载期间显示备选内容,确保了平滑的加载过渡。
29900
|
10月前
|
算法Java关系型数据库
Java中到底有哪些锁
【9月更文挑战第24天】在Java中,锁主要分为乐观锁与悲观锁、自旋锁与自适应自旋锁、公平锁与非公平锁、可重入锁以及独享锁与共享锁。乐观锁适用于读多写少场景,通过版本号或CAS算法实现;悲观锁适用于写多读少场景,通过加锁保证数据一致性。自旋锁与自适应自旋锁通过循环等待减少线程挂起和恢复的开销,适用于锁持有时间短的场景。公平锁按请求顺序获取锁,适合等待敏感场景;非公平锁性能更高,适合频繁加解锁场景。可重入锁支持同一线程多次获取,避免死锁;独享锁与共享锁分别用于独占和并发读场景。
|
11月前
|
程序员编译器数据处理
汇编高手秘籍:解锁性能优化新境界,用汇编语言让你的程序飞起来!
【8月更文挑战第31天】汇编语言作为编程基石,其高效性能备受推崇。尽管现代软件开发更偏爱高级语言,但在性能要求极高的场景下,汇编优化仍不可或缺。本文通过示例代码介绍四种优化技巧:循环展开、寄存器分配、指令重排及SIMD指令使用,显著提升执行效率。同时强调分析性能瓶颈、测试优化效果及保持代码可读性的重要性,助力开发者在关键代码路径上实现性能突破。
45700
|
移动开发前端开发JavaScript
前端和后端限制文件大小的具体实现方式
【5月更文挑战第3天】前端限制文件大小可使用HTML5的&quot;accept&quot;和&quot;maxSize&quot;属性或JavaScript的File API,后端则可通过判断文件字节大小、使用第三方库如Apache Commons FileUpload,或者在服务器框架如Flask、Spring中设置限制。Nginx也可作为反向代理设定上传限制,但可能影响用户体验。
79844
|
12月前
|
SQL监控druid
MySQL连接池DataSource怎么使用?
**摘要:** 本文探讨了数据库连接池在高并发Web应用中的重要性,特别聚焦于阿里巴巴的DruidDataSource。DruidDataSource是一个高效的Java数据库连接池,包含监控、SQL防护和日志功能。文中通过示例展示了如何配置和使用DruidDataSource,包括在Java应用中的直接配置和在Spring Boot中的集成,并提到了启用SQL监控。此外,还分享了设置连接池参数的技巧,如合理设定初始、最大和最小连接数,并强调了定期监控和使用内置监控工具优化性能的重要性。
|
存储数据采集JavaScript
php对接阿里云API调用企业税号查询的高级实战案例解析(下拉筛选查询、远程调用API、xm-select组件应用)
php对接阿里云API调用企业税号查询的高级实战案例解析(下拉筛选查询、远程调用API、xm-select组件应用)
8143131

热门文章

最新文章

  • 1
    DataWorks+Hologres:打造企业级实时数仓与高效OLAP分析平台
    22
  • 2
    基于YOLOv8的FPS射击类游戏人物识别项目|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!
    22
  • 3
    豆蔻妇科大模型再突破:钉钉行业训练平台+精标数据SFT ,准确率从 77.1%上升至 90.2%
    26
  • 4
    如何开发ERP系统中的计划管理板块(附架构图+流程图+代码参考)
    25
  • 5
    关于大模型的一些知识
    20
  • 6
    金属材料表面六种缺陷类型数据集 | 适用于YOLO等视觉检测模型(1800张图片已划分、已标注)
    16
  • 7
    Windows IIS 10如何配置自签名SSL并实现自动跳转
    17
  • 8
    看不见就管不好?——机器学习如何把供应链“照亮”!
    24
  • 9
    数据不止防故障,还能防攻击?
    14
  • 10
    城市早高峰太难了?其实你堵的是数据不是车!
    16