学习路径:https://coding.imooc.com/class/270.html
-
前言
享元模式一般不单独使用。其作用类似缓存,一块内存区域多端共享,减少重复操作,提高效率。享元模式和单例模式的主要区别是,单例模式的对象一旦被创建就常驻内存,享元模式则可以擦除创建出来的对象。 -
应用场景
1.系统底层开发,如JDK的Integer.valueof(x),x在[-128,127]这个区间的时候会直接去取内存中的“常量”对象,不在这个区间的就会new一个新对象。
2.某个业务需要反复创建模板,模板是相同或者相似的,就可以将内存的一块区域专门存放模板。减少了每次都要new 一个对象,避免多次开辟新的内存区域。
3.以员工做汇报为场景,每次汇报都需要提供模板信息,那么新来的经理必须手上要有汇报的模板。
/**
- 雇员接口,持有一个报告的方法
*/
public interface Employee {
void report();
}
/**
* 经理掌握很多数据,适合作为汇报者
*/
public class Manager implements Employee {
@Override
public void report() {
System.out.println(reportContent);
}
// 经理所属的部门
private String department;
// 每个经理都要指定部门才可以实例化。
public Manager(String department) {
this.department = department;
}
// 汇报的内容
private String reportContent;
// 提供外部填写汇报内容的方法
public void setReportContent(String reportContent) {
this.reportContent = reportContent;
}
}
/**
* 员工工厂(工厂模式 + 单例模式 + 享元模式)
*/
public class EmployeeFactory {
// 一个部门对应一个部门经理,以部门名称为key,创建单例容器
private static final Map<String, Employee> MANAGER_MAP = new HashMap<>();
public static Employee getManager(String department){
Manager manager = (Manager) MANAGER_MAP.get(department);
// 如果找不到输入的部门所对应的经理,就创建一个
if (manager == null){
// 新的部门经理创建出来啦
manager = new Manager(department);
System.out.print("创建部门经理" + department);
// 创建一个汇报模板,这里是享元模式
String reportContent = department + "部门汇报:此次报告的主要内容";
// 将模板赋值给经理
manager.setReportContent(reportContent);
System.out.println(" 创建报告"+reportContent);
// 新来的部门经理加入单例容器
MANAGER_MAP.put(department, manager);
}
return manager;
}
}
- 拓展
Tomcat的对象池中,使用双端队列来保存连接完成的对象。并提供生命周期函数,未被销毁的对象,可以在队列中反复取出来用。类似的还有Android的Activity等生命周期维持的对象。是享元模式的实现