需要下载demo
demo: https://gitee.com/minstrel01/Design-Pattern-demo.git flyweight_pattern
在报考系统中,我们完全可以重新建立一个类作为外部状态,这样才完全符合面向对象编程的理念
//外部类
public class ExtrinsicState {
//考试科目
private String subject;
//考试地点
private String location;
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
@Override
public boolean equals(Object object){
if (object instanceof ExtrinsicState){
ExtrinsicState state = (ExtrinsicState) object;
return state.getLocation().equals(location) && state.getSubject().equals(subject);
}
return false;
}
@Override
public int hashCode(){
return subject.hashCode() + location.hashCode();
}
}
注意 一定要覆写equals方法和hashcode方法,否则它作为HashMap中的key值时根本没有意义的,只有hashCode值相等,并且equals返回结果为true,两个对象才相等,也只有在这种情况下,才有可能从对象池中查找获得对象
如果把一个对象作为Map类的键值,一定要确保重写了equals方法和hashCode方法,否则会出现通过键值搜索失败的情况,例如map.get(object)等方法
//使用外部类的享元工厂
public class SignInfoFactory2 {
//池容器
private static HashMap<ExtrinsicState,SignInfo> pool = new HashMap<>();
//从池中获得对象
public static SignInfo getSignInfo(ExtrinsicState key){
//设置返回对象
SignInfo result = null;
//池中没有该对象,则建立,并放入池中
if (!pool.containsKey(key)){
result = new SignInfo();
pool.put(key,result);
}else {
result = pool.get(key);
}
return result;
}
}
public class Client {
public static void main(String[] args) {
//使用外部类作为外部状态
ExtrinsicState state1 = new ExtrinsicState();
state1.setLocation("上海");
state1.setSubject("科目1");
SignInfoFactory2.getSignInfo(state1);
ExtrinsicState state2 = new ExtrinsicState();
state2.setLocation("上海");
state2.setSubject("科目2");
long currentTime = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
SignInfoFactory2.getSignInfo(state2);
}
long tailTime = System.currentTimeMillis();
System.out.println("使用时间为"+ (tailTime - currentTime) +"ms");
//以String类型作为外部状态
String key1 = "科目1上海";
String key2 = "科目2上海";
//初始化对象池
SignInfoFactory.getSignInfo(key1);
long currentTime1 = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
SignInfoFactory.getSignInfo(key2);
}
long tailTime1 = System.currentTimeMillis();
System.out.println("使用时间为"+ (tailTime1 - currentTime1) +"ms");
}
}
结果如下
使用外部类的效率总是低于使用String的,所以如果使用自己编写的类作为类的外部状态,必须覆写equals方法和hashCode方法,而且执行效率还比较低,这种吃力不讨好的事最好别做,外部状态最好以java的基本类型作为标示 如String,或者 int等,可以大幅度提升效率