flyweight模式的出现是因为面向对象开发有时在设计和性能方面存在相悖的情况,当内存因为对象过多而产生泄露导致宕机,而这又是由于业务本身需求的时候,我们就不得不采用以时间换空间的策略了.
这里便引入了亨元模式.
我理解的亨元模式是抽取对象中共有的属性作为元,产生对象并放在池中(显然此时创建的对象要少的多),然后在用到的时候直接从池中取得.
但这样做很显然会涉及到同步的问题,此时有N个用户需要该对象,但此时又加了锁,那只能进入等待队列中.该怎么样解决,因为我实际并没有在专案中用到过该模式,所以也不甚明白,总之感觉就算效率低下也总比宕机要好的多.
亦有有经验人在解决同步时称:在使用享元模式时,对象池中的享元对象尽量的多,多到足够满足业务为止。
此为经验之谈,以后遇到应该注意.
代码是取自别人:
package pattern.flyweight;
public class SignInfo {
// 报名人员的ID
private String id;
// 考试地点
private String location;
// 考试科目
private String subject;
// 邮寄地址
private String postAddress;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getPostAddress() {
return postAddress;
}
public void setPostAddress(String postAddress) {
this.postAddress = postAddress;
}
}
package pattern.flyweight;
import java.util.HashMap;
public class SignInfoFactory {
// 报名信息的对象工厂
private static HashMap<ExtrinsicState, SignInfo> pool = new HashMap<ExtrinsicState, SignInfo>();
// 报名信息的对象工厂
public static SignInfo getSignInfo() {
return new SignInfo();
}
// 从池中获得对象
public static SignInfo getSignInfo(ExtrinsicState key) {
// 设置返回对象
SignInfo result = null;
// 池中没有该对象,则建立,并放入池中
if (!pool.containsKey(key)) {
System.out.println(key + "----建立对象,并放置到池中");
result = new SignInfo();
pool.put(key, result);
} else {
result = pool.get(key);
System.out.println(key + "---直接从直池中取得");
}
return result;
}
}
package pattern.flyweight;
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 obj) {
if (obj instanceof ExtrinsicState) {
ExtrinsicState state = (ExtrinsicState) obj;
return state.getLocation().equals(location)
&& state.getSubject().equals(subject);
}
return false;
}
@Override
public int hashCode() {
return subject.hashCode() + location.hashCode();
}
}
package pattern.flyweight;
public class Client {
public static void main(String[] args) {
ExtrinsicState state1 = new ExtrinsicState();
state1.setSubject("科目1");
state1.setLocation("上海");
SignInfoFactory.getSignInfo(state1);
ExtrinsicState state2 = new ExtrinsicState();
state2.setSubject("科目1");
state2.setLocation("上海");
// 初始化对象池
SignInfoFactory.getSignInfo(state1);
// 计算执行10万次需要的时间
long currentTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
SignInfoFactory.getSignInfo(state2);
}
long tailTime = System.currentTimeMillis();
System.out.println("执行时间:" + (tailTime - currentTime) + " ms");
}
}
需要注意的是外蕴一般要用java的基本类型如int,String等,像以上用自己定义的object来做外酝的话,效率相较低下.