java设计模式——享元模式
一. 定义与类型
定义:提供了减少对象数量从而改善应用所需的对象结构的方式,运用共享技术有效地支持大量细粒度的对象
类型:结构性
二. 使用场景
(1) 常常应用于系统底层的开发,以便解决系统的性能问题
(2) 系统有大量相似对象,需要缓冲池的场景
三. 优缺点
优点:
(1) 减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率
(2) 减少内存之外的其他资源占用
缺点:
(1) 关注内/外状态,关注线程安全问题
(2) 使系统,程序的逻辑复杂化
四.享元——扩展
内部状态
外部状态
五. 相关设计模式
享元模式和代理模式
代理模式就是代理一个类,如果生成这个代理类需要花费的资源和时间比较多,就可以使用享元模式,提高系统的速度
享元模式和单例模式
单例模式中的容器单例就是享元模式的一种使用
六. Coding
以一个业务场景为例,假设每年年底的时候公司中的部门经理都需要写年终报告,但是可能不止要报告一次,需要重复报告。
使用享元模式,可以很好的完成上面的例子。
先创建一个接口:
/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2019-02-12 10:01
**/
public interface Emplyee {
void report();
}
再创建一个经理实体类,来实现接口
/**
* @program: designModel
* @description: 部门manager
* @author: YuKai Fan
* @create: 2019-02-12 10:01
**/
public class Manager implements Emplyee {
public void report() {
System.out.println(reportContent);
}
private String title = "部门经理";
private String department;//部门
private String reportContent;//报告内容 public Manager(String department) {
this.department = department;
} public void setReportContent(String reportContent) {
this.reportContent = reportContent;
}
}
在创建一个员工工厂,通过工厂在获取manager,因为只需要manager做报告,不需要employee。
/**
* @program: designModel
* @description: 员工工厂
* @author: YuKai Fan
* @create: 2019-02-12 10:04
**/
public class EmployeeFactory {
//因为在享元模式中,一般要考虑线程安全问题,但是还是要看业务场景来使用
private static final Map<String, Emplyee> EMPLYEE_MAP = new HashMap<String, Emplyee>(); public static Emplyee getManager(String department) {
Manager manager = (Manager) EMPLYEE_MAP.get(department);
if (manager == null) {
manager = new Manager(department);
System.out.print("创建部门经理:" + department);
String reportContent = department + "部门汇报:此次报告的主要内容是。。。。";
manager.setReportContent(reportContent);
System.out.println(" 创建报告:" + reportContent);
EMPLYEE_MAP.put(department, manager);
}
return manager;
}
}
应用层:
/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2019-02-12 10:08
**/
public class Test {
private static final String departments[] = {"RD", "QA", "PM", "BD"}; public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
String department = departments[(int) (Math.random() * departments.length)];
Manager manager = (Manager) EmployeeFactory.getManager(department);
manager.report();
}
}
}
结果:

UML类图:

从结果可以看出,当部门经理做报告时只需要创建一次即可,下次不需要再次创建。减少了对象的创建
在上面的代码例子中,department相当于外部状态。因为它依赖于外部的传入,为了方便理解,创建一个title属性,它就是一个内部状态,它不随外部状态department的变化而变化。
七. 源码分析
(1)
Integer类就是典型的享元模式的例子

Integer.valueOf中有一个IntegerCache,上面的代码中就对传入的值进行判断。如果是从IntegerCache中取出就直接返回,否则就new一个Integer对象。这也就是如果传入的int值不在固定的范围类,它们做==的时候一定是false,因为不是同一个对象。其中low=-128,high=127.


还有Long类的valueOf,也是同上的道理。
(2)
tomcat中的GenericObjectPoolConfig连接池
java设计模式——享元模式的更多相关文章
- 【设计模式】Java设计模式 - 享元模式
Java设计模式 - 享元模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...
- JAVA 设计模式 享元模式
用途 享元模式 (Flyweight) 运用共享技术有效地支持大量细粒度的对象. 享元模式是一种结构型模式. 结构
- Java设计模式-享元模式(Flyweight)
享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查 ...
- java设计模式---享元模式
享元模式 顾名思义:共享元对象.如果在一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必为每一次使用创建新的对象. 享元模式是为数不多的.只为提升系统性能而生的设计模式.它的主要作用就 ...
- Java设计模式—享元模式
享元模式:是池技术的重要实现方式. 定义如下: 使用共享对象可有效地支持大量的细粒度的对象. 个人理解:享元模式利用共享对象的技术,解决了Java中内存溢出的问题. 享元模式的定义为我们提出了两个要求 ...
- 8. 星际争霸之php设计模式--享元模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- C++设计模式——享元模式
本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.如果这篇文章对你有帮助,你可以请我喝杯咖啡. » 本文链接:http:// ...
- [工作中的设计模式]享元模式模式FlyWeight
一.模式解析 Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意.享元模式是对象的结构模式.享元模式以共享的方式高效地支持 ...
- 设计模式-享元模式(FlyWeight)
一.概念 享元模式是对象的结构模式,它以共享的方式高效的支持大量的细粒度对象,减少对象的数量,并达到节约内存的目的. 享元对象能够做到共享的关键,主要是区分了内部状态和外部状态,内部状态是对象是在建立 ...
随机推荐
- 为啥Spring和Spring MVC包扫描要分开?
背景: 最近在搭建新工程的时候发现有些Spring的配置不是很了解,比如Spring 配置里面明明配置了component-scan,为啥Spring MVC配置文件还需要配置一下,这样岂 ...
- tcp发送缓冲区学习
https://blog.csdn.net/ysu108/article/details/7764461 Nginx 模块开发书上有内容 陶辉博客也可以
- .NET接收邮件下载邮件附件——openpop.net
使用OpenPop.Net接收邮件很方便,下面是接收下载邮件附件的代码 OpenPop.Net下载地址 https://sourceforge.net/projects/hpop/ public cl ...
- Android中的APinner2
Spinner提供了从一个数据集合中快速选择一项值的办法.默认情况下Spinner显示的是当前选择的值,点击Spinner会弹出一个包含所有可选值的dropdown菜单,从该菜单中可以为Spinner ...
- pat1043. Is It a Binary Search Tree (25)
1043. Is It a Binary Search Tree (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN ...
- CentOS7 安装oracle 客户端
参考 http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html 下载 oracle-instantclient11. ...
- jQuery UI dialog 隐藏默认关闭按钮
var O_dialog = $("#dialog-modal"); O_dialog.dialog({ closeOnEscape: false, width: 250, hei ...
- webapi 开启跨域支持
1.Global文件: GlobalConfiguration.Configuration.EnableCors(); 2.需要跨域的action或controller添加跨域规则 [EnableCo ...
- tp3.2水印上传文件
<html> <html lang="en"><head> <meta charset="UTF-8"> ...
- vue中 eCharts 自适应容器
在 vue 脚手架开发中,echarts图表自适应容器的方法: 父组件: <template> <div class="statistics_wrap"> ...