一、定义
定义:提供了减少对象数量从而改善应用所需的对象结构的方式(减少对象的创建,减少内存的占用,提供性能)
运用共享技术有效地支持大量细粒度的对象
类型:结构型
二、适用场景
1、常常应用于系统底层的开发,以便解决系统的性能问题。
2、系统有大量相似对象、需要缓冲池的场景
三、优点
减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率
减少内存之外的其他资源占用(如New对象创建需要时间的减少)
四、缺点
关注内/外部状态、关注线程安全问题
使系统、程序的逻辑复杂化
五、扩展
1、内部状态
在享元对象的内部,并且不会随着环境的改变而改变的共享部分。
2.外部状态
在享元对象的外部,随着环境改变而改变的
六、相关设计模式
1、享元模式和代理模式
如果生成的代理类,生成和花费的时间比较多,那么可以使用享元模式提高程序的处理速度。
七、Codeing(场景:领导要求部门经理做报告)
1. 创建Employee 接口
public interface Employee { void report(); }
2. 创建Manager 类
public class Manager implements Employee { private String department; private String reportContent; //头衔 private String title = "部门经理"; public Manager(String department) { this.department = department; } public void setReportContent(String reportContent) { this.reportContent = reportContent; } @Override public void report() { System.out.println(reportContent); } }
这里department依赖外部传入,也就是外部状态。
title是头衔,不会改变,也就是内部状态。
3.创建EmployeeFactory 工厂类。里面有一个内部容器EMPLOYEE_MAP 。 如果没有创建Manager实例,则创建,并保存在EMPLOYEE_MAP 。
如果已经创建,则在EMPLOYEE_MAP 中取出。
public class EmployeeFactory { private static final Map<String, Employee> EMPLOYEE_MAP = new HashMap<>(); public static Employee getManager(String department){ Manager manager = (Manager) EMPLOYEE_MAP.get(department); if(manager == null){ manager = new Manager(department); System.out.print("创建部门经理:" + department); String reportConent = department + ":此次报告的内容是。。。"; manager.setReportContent(reportConent); System.out.println(" 创建报告:" + reportConent); EMPLOYEE_MAP.put(department,manager); } return manager; } }
4、创建测试类
public class Test { private final static String departments[] = {"RD","QA","PM"}; 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(); } } }
5. UML图
八、在源码中的应用
1、Integer类valueOf方法(Long类的valueOf方法)
public static Integer valueOf(int var0) { assert Integer.IntegerCache.high >= 127; return var0 >= -128 && var0 <= Integer.IntegerCache.high?Integer.IntegerCache.cache[var0 + 128]:new Integer(var0); }