[设计模式]享元模式
享元模式是对象池的一种实现,它的英文名称叫做Flyweight,代表轻量级的意思。享元模式用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,来缓存可
共享的对象,达到对象共享、避免创建过多对象的效果,这样一来就可以提升性能、避免内存移除等。
享元对象中的部分状态是可以共享,可以共享的状态成为内部状态,内部状态不会随着环境变化;不可共享的状态则称之为外部状态,它们会随着环境的改变而改变。在享元
模式中会建立一个对象容器,在经典的享元模式中该容器为一个Map,它的键是享元对象的内部状态,它的值就是享元对象本身,。客户端程序通过这个内部状态从享元工厂中获取
享元对象,如果有缓存则使用缓存对象,否则创建一个享元对象并且存入容器中,这样一来就避免了创建过多对象的问题。
定义:
使用共享对象可有效地支持大量的细粒度的对象。
使用场景:
1.系统中存在大量的相似对象。
2.细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身价。
3.需要缓冲池的场景。
UML类图:
Flyweight :享元对象抽象基类或者接口
ConcreteFlyweight :具体的享元对象。
FlyweightFactory :享元工厂,负责管理享元对象池和创建享元对象。
示例:
用买火车票做为例子,无数人用刷票软件在向服务端发出请求,对于每个请求服务器都必须做出应答。在用户设置好出发地和目的地之后,每次请求都返回一个的车票结果,假设每次返回的只有一躺列车的车票。那么当数以万计的人不间断的请求数据时,如果每次都重新创建一个的车票结果,那么必然会造成大量重复对象的创建、销毁,使得
GC任务繁重、内存占用率高居不下。从A到B的车辆是有限的,车上的铺位也就那么几种,我们将这些可以公用的对象缓存起来,在用户查询时优先使用缓存,如果没有缓存则重新创建,这样就将成千上万的对象变为了可选择的有限数量。
public interface Ticket {//展示车票信息的方法public void showTicketInfo(String bunk);
}
//火车票类
public class TrainTicket implements Ticket{public String from; //始发地public String to; //目的地public String bunk; //铺位public int price;public TrainTicket(String from, String to) {this.from = from;this.to = to;}@Overridepublic void showTicketInfo(String bunk) {price = new Random().nextInt(300);System.out.println("购买从" + from + "到" + to + "的" + bunk + "火车票" + ",价格 : " + price);}}
享元模式通过消息池的形式有效地减少了重复对象的存在,它通过内部状态标识某个种类的对象,外部程序根据这个不会变化的内部状态从消息池中取出对象。使得同一类对象可以被复用,避免大量重复对象。
public class TicketFactory {static Map<String,Ticket> sTicketMap = new ConcurrentHashMap<String,Ticket>();public static Ticket getTicket(String from, String to){String key = from + "-" + to;if(sTicketMap.containsKey(key)){System.out.println("use cache : " + key);return sTicketMap.get(key);}else {System.out.println("create object : " + key);Ticket ticket = new TrainTicket(from, to);sTicketMap.put(key, ticket);return ticket;}}//我们在TicketFactory添加了一个map容器,并且以出发地“-”目的地为键、以车票对象作为值存储车票对象。这个map的键就是我们说的内部状态,如果没有缓存则创建一个对象,并且将这个对象//缓存到map中,下次再有这类请求时则直接从缓存中获取。这样即使有10000个请求北京到青岛的车票信息,那么出发地是北京,目的地是青岛的车票对象只有一个。这样就从这个对象从10000减到了1个,//避免了大量的内存占用及频繁的GC操作。
}
public class Client {public static void main(String[] args) {Ticket tick1 = TicketFactory.getTicket("北京", "青岛");tick1.showTicketInfo("上铺");Ticket tick2 = TicketFactory.getTicket("北京", "青岛");tick1.showTicketInfo("中铺");Ticket tick3 = TicketFactory.getTicket("北京", "青岛");tick1.showTicketInfo("下铺");}//运行结果:/*create object : 北京-青岛购买从北京到青岛的上铺火车票,价格 : 154use cache : 北京-青岛购买从北京到青岛的中铺火车票,价格 : 101use cache : 北京-青岛购买从北京到青岛的下铺火车票,价格 : 59*/
}
从结果可以看出,只有第一次查询车票时创建了一次对象,后续的查询都使用的是消息池中的对象。这其实就是相当于一个对象缓存,避免了对象的重复创建与回收。
总结:
享元模式实现比较简单,但是它的作用在某些场景确实极其重要。它可以大大减少应用程序创建的对象,降低程序内存的占用,增加程序的性能,但它同时也提高了系统的复杂性,需要分离出外部状态和内部状态,而且外部状态具有固化特性,不应该随内部改变而改变,否则导致系统的逻辑混乱。
优点:在于它大幅度地降低中对象的数量。但是,它做到这一点所付出的代价也是很高的;
缺点:
1.享元模式使得系统更加复杂,为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。
2.享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
[设计模式]享元模式相关推荐
- Python设计模式-享元模式
Python设计模式-享元模式 基于Python3.5.2,代码如下 #coding:utf-8class Coffee:name = ""price = 0def __init_ ...
- 10-Python与设计模式--享元模式
10-Python与设计模式--享元模式 一.网上咖啡选购平台 假设有一个网上咖啡选购平台,客户可以在该平台上下订单订购咖啡,平台会根据用户位置进行线下配送.假设其咖啡对象构造如下: class Co ...
- 设计模式--享元模式实现C++
/********************************* *设计模式--享元模式实现 *C++语言 *Author:WangYong *Blog:http://www.cnblogs.co ...
- 【设计模式】Java设计模式 - 享元模式
[设计模式]Java设计模式 - 享元模式
- Unity设计模式——享元模式(附代码)
Unity设计模式--享元模式(附源码) 享元Flyweight模式是什么 享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的 ...
- 第二十二章 Caché 设计模式 享元模式
文章目录 第二十二章 Caché 设计模式 享元模式 定义 优点 使用场景 结构图 描述 完整示例 实体类 抽象享元角色 实现享元角色 享元工厂 调用 思考 第二十二章 Caché 设计模式 享元模式 ...
- JavaScript设计模式-享元模式
JavaScript设计模式-享元模式 概念 例子 内部状态与外部状态 享元模式的通用结构 例子 总结 github仓库地址:点击 [设计模式例子](https://github.com/fanhua ...
- JAVA 设计模式 享元模式
用途 享元模式 (Flyweight) 运用共享技术有效地支持大量细粒度的对象. 享元模式是一种结构型模式. 结构 图-享元模式结构图 Flyweight : 它是所有具体享元类的超类或接口,通过这个 ...
- java设计模式---享元模式
Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己 对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广 泛,遵循一定的编程模式,才能使自己的 ...
- PHP设计模式——享元模式
声明:本系列博客参考资料<大话设计模式>,作者程杰. 享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的 ...
最新文章
- 数据库读取image类型发送到前端显示图片
- Git同步本地项目文件到github
- [转载] Java面试题大全(2020版)
- 近期可能会研究和讨论的个人动向
- clion 插件_IDEA必备插件系列-Rainbow
- Google Puppeteer加入到headless Chrome的工具行列
- 2018年计算机基础模拟试题,2018年大学计算机基础试题及答案
- XML PUBLISHER输出excel存在科学计数
- Mac桌面上找不到或无法显示USB问题
- 三、spring中高级装配(1)
- 基于java的宠物领养交流网站
- 印象笔记三级目录_如何建立印象笔记的三层目录构架
- html 星星字体,做华丽的星星文字效
- 下载B站、秒拍等视频网站视频
- kubernetes 核心组件之 Controller Manager
- mongodb 创建只读用户
- 从零开始 教你如何搭建Discuz!4.1论坛(图)
- Codeforces Round #516 E. Dwarves, Hats and Extrasensory Abilities
- python中screen用法_screen命令的使用
- 抖~~音 无水印video 下载
热门文章
- java解决properties中中文乱码问题
- Excel:将图片制作成九宫格形式
- 大赛通知|12万奖金!BMW宝马发起编程新赛事,四大赛道等你挑战!
- 超声波电路板驱动线路设计
- python3.9安装_Python 3.9下载 Python 3.9.0 for Windows 官方安装正式版 32位/64位 下载-脚本之家...
- JDK动态代理学习笔记
- 2345安全卫士卸载不了怎么办?
- endnote转化为文字格式
- pythonif语句如何循环_pythonif语句如何循环
- 关于JDBC连接MySQL的时候出现警告:Establishing SSL connection without server‘s identity verification is not recom