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)
一.概念 享元模式是对象的结构模式,它以共享的方式高效的支持大量的细粒度对象,减少对象的数量,并达到节约内存的目的. 享元对象能够做到共享的关键,主要是区分了内部状态和外部状态,内部状态是对象是在建立 ...
随机推荐
- Spark为什么比Hadoop好?
(1)Spark计算速度远胜于Hadoop的原因之一就在于中间结果是缓存在内存而不是直接写入到disk Hadoop每次计算先写磁盘,下次计算先从磁盘读,计算结果再写磁盘,如此往复.这对于迭代计算,是 ...
- xshell如何传输文件-yum
1.安装 sudo yum install lrzsz -y 2.检查是否安装成功 #rpm -qa |grep lrzsz 出现如下,表示安装成功 3.上传文件的执行命令: #rz 就会打开本地选 ...
- python fork函数
import os print('---父进程id:%s----'%(os.getpid())) pid=os.fork()#只能在liunx环境下执行 print('---%s---' % (os. ...
- RTT之shell
两种shell的切换:如果打开了FINSH_USING_MSH而没有打开FINSH_USING_MSH_ONLY,finsh同时支持两种c-style模式与msh模式,但是默认进入c-style模式, ...
- (转)shell中各种括号的作用()、(())、[]、[[]]、{}
shell中各种括号的作用().(()).[].[[]].{} 原文:http://www.jb51.net/article/60326.htm http://blog.csdn.net/good_h ...
- 【input】——数据传入后台
1.复选框 checkbox <label class="checkbox"> <input type="checkbox" name=&qu ...
- 使用Aspose.Cell控件实现Excel高难度报表的生成
1.使用Aspose.Cell控件实现Excel高难度报表的生成(一) http://www.cnblogs.com/wuhuacong/archive/2011/02/23/1962147.html ...
- iOS-swift-函数和闭包
一.函数 关键字:func 参数列表用 , 分割 使用 -> 分割参数和返回值 func greet(person: String, day: String) -> String { re ...
- 在基于WCF开发的Web Service导出WSDL定义问题及自定义wsdl:port 名称
在契约优先的Web服务开发过程中,往往是先拿到WSDL服务定义,各家开发各自的服务实现或客户端,然后互相调用. 尽管Web Service的标准已经发布很多年,但各 ...
- Mysql远程连接授权IP
新增法 我们现在增加一个'username'用户,密码为'password',让其能够从外部访问MYSQL. grant all on * to 'username' identified by ...