概念
享元模式又称为轻量级模式,它是一种对象结构型模式。该模式主要用于减少创建对象的数量,通过调用已创建的对象实现共享一个单元,从而降低运行的成本,提高性能。
实现
简单地实现享元模式
public class fw1 {
public static void main(String[] args) {
String str1 = "ctb";
String str2 = "ctb";
String str3 = new String("ctb");
String str4 = new String("ctb");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str3.intern() == str1);
System.out.println(str3 == str4);
System.out.println(str3.intern() == str4.intern());
}
}
实验结果:
解释:第一个和第二个创建的时候为常量,所有他们都是指向常量池中的同一个对象,str3和str4是创建一个新的对象,他们的地址不同,所以指向的对象不同,当str3调用intern()方法时,指的是str3指向常量池的那一部分,所以第三个判断条件为真。这里常量池的设计就用了享元模式,每当调用"ctb"时,都是从常量池中找出来,而不是重新创建的。
样例二:我们都是学生时代的过来人,每次考完试,我们都会根据自己的名字和学号查看自己成绩,现在假定学生通过姓名,学号,科目查看自己单科成绩:
首先定义一个成绩单的接口:
/**
* 定义成绩单的接口
*/
public interface Report {
public void show(String subject);
}
具体实现这个成绩单:
public class SchoolReport implements Report {
//定义成绩单属性-姓名
private String name;
//定义成绩单属性-学号
private int id;
//定义成绩单属性-成绩
private static int score = new Random().nextInt(150);
public SchoolReport(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public void show(String subject) {
System.out.println("姓名:" + this.name + " 学号" + this.id + " " +subject + "成绩为:" + this.score);
}
}
定义一个成绩系统用于查询成绩:
/**
* 定义一个成绩系统用于查询成绩
*/
public class ReportSystem {
public static Report queryReport(String name,int id){
return new SchoolReport(name,id);
}
}
学生端进行测试:ctb去查成绩了:
public class Student {
public static void main(String[] args) {
Report report = ReportSystem.queryReport("ctb",5);
report.show("语文");
}
}
实现结果:
分析:我们可以看出每个人在查看成绩的时候都会在查询成绩系统中重新new一个对象出来,所以当小明,小白等多个人都去查看ctb的成绩的时候,那么就会重复new出多个不同的对象,从而使得就一个ctb的成绩把整个学校的查询成绩系统给搞崩了。
因此我们对查询成绩系统进行修改,让他不用重新创建对象,第一次创建对象的时候,把他的成绩放入内存中,当第二次查询的时候,直接从内存中进行调用。
进一步优化查询成绩系统:
/**
* 定义一个成绩系统用于查询成绩
*/
public class ReportSystem {
//定义一个容器存放内存
private static Map<String,Report> map = new ConcurrentHashMap<>();
public static Report queryReport(String name, int id){
//判断容器中是否包含已有数据
if(ReportSystem.map.containsKey(name)){
System.out.println("通过缓存实现");
return ReportSystem.map.get(name);
}
Report report = new SchoolReport(name,id);
System.out.println("创建对象实现");
//放入容器中
ReportSystem.map.put(name,report);
return report;
}
}
2个同学查询ctb成绩:
public class Student {
public static void main(String[] args) {
Report report = ReportSystem.queryReport("ctb",5);
report.show("语文");
Report report1 = ReportSystem.queryReport("ctb",5);
report1.show("语文");
}
}
实现结果:
优点:在一定程度上,减少了对象的创建,极大增强了系统的性能。
缺点:系统需要分离出内部状态和外部状态,使系统变得复杂。
本文的代码:https://pan.baidu.com/s/1ofkUpquobPA0qcj591cI7A
提取码:otot