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连接池
最新文章
- linux 内核源代码
- Python Windows环境下安装Python集成开发环境 学习之路(一)
- 【JS】defer / async
- WCF学习笔记之地址
- Redis源代码分析(二十八)--- object创建和释放redisObject物
- 11g R2RAC Dynamic remastering
- linux视频学习7(ssh, linux启动过程分析,加解压缩,java网络编程)
- ASP.NET Core MVC和Visual Studio入门
- 企业IT管理员IE11升级指南【12】—— 兼容视图列表介绍
- 【题解】Luogu P4121 [WC2005]双面棋盘
- php单点登录
- Kotlin 使用类似C# 的yield功能
- Navicat远程连接不上mysql解决方案
- Confluence 6 整合到其他数据库
- Java 创建一个窗口,使其启动时位于屏幕中间
- 在vue2.x项目中怎么引入Element UI
- centos 支持安装libsodium
- day31-软件开发规范
- js如何用json 读取C#的Dictionary
- 新版Java为什么要修改substring的实现