设计模式-享元模式


定义

运用共享的技术有效地支持大量细粒度的对象。

场景

  • 系统中有许多相似的对象
  • 细粒度的对象具有接近的外部状态,而内部状态与环境无关
  • 需要缓冲池的场景

例子

对于系统中的用户都有一个地址(省份+市区+县+乡镇+其他)

其实到线级别25(省)*30*10(县)=7500(随便写的数据)

假如有这么多到县级别的地址。但是系统可能有千万的用户,如果对于每个访问的用户的地址都对这些创建对象,则会造成很大的空间浪费。

所以可以对于地址这些地址进行共享,只是对于更细粒度的数据生成私有的存储。

public class User {
public String name;
public String province;
public String city;
public String county;
public String address;
}

普通的User类每生成一个对象,对于province、city、county都申请一份空间

可以将这些数据做成共享的

public class User {
private String name;
private County county;
private String address;
public void setCounty(String key) {
county = CountyFactory.getCountty(key);
}
/**
* @return the county
*/
public County getCounty() {
return county;
}
}

public class County {
private String province;
private String city;
private String county;

public County(String province, String city, String county) {
this.province = province;
this.city = city;
this.county = county;
}

/**
* @return the province
*/
public String getProvince() {
return province;
}

/**
* @return the city
*/
public String getCity() {
return city;
}

/**
* @return the county
*/
public String getCounty() {
return county;
}

public class CountyFactory {

public static Map pool = new HashMap();
public static County getCountty(String key) {
if(pool.containsKey(key)) {
return pool.get(key);
}else {
String[] infos = key.trim().split(":");
if(infos.length<3) {
return null;
}
County county = new County(infos[0], infos[1], infos[2]);
pool.put(key, county);
return county;
}
}
}

这样就不会造成空间的浪费。

在这里有两个概念

内部状态:可以共享的数据County

外部状态:随着环境改变的数据

java里面的线程池,线程为内部状态,但是真正执行的逻辑run为每个外部状态

当然在上面的例子没有考虑多线程状态,实际使用中需要考虑

例子中不同的User可以同时持有一个County,线程池则只能被一个Runnable使用,当池达到最大可以容纳,其他到达的请求会有不同的策略一般为在队列中等待