单例模式垄断了对资源的访问,避免了多次生成带来的重复浪费。
但有时候,我们并没有这么严格的限制,还是希望多几个干活的,或者说
我们的实例有部分的重用功能,但又不能像单例那样只有一个,还是需要很多的实例。
具体如:
我们服务器缓存了100W个用户的信息,但是有一些冗余,例如我们的年龄只有100个取值,最多150是不是!但我们有100个用户,每个都有一个单独的年龄字段,相对是有点多余的,如果可以只压缩到100个的话。或者我们的用户里面的省会信息,也就34个!
好了,废话那么多,到底这个享元应该怎么写呢?
代码实现
我们的用户
public class UserInfo {
private String uuid;
private int age;
private String name;
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这个就是我们的用户啦,配一个ID,一个年龄,一个名字属性。
接着我们设计一个用户的对象池,他的KEY为年龄。
public class UserInfoPool extends UserInfo {
private String key;
public UserInfoPool(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
然后我们的工厂,他负责生成用户,保存用户信息。
public class UserInfoFactory {
private static HashMap<String, UserInfo> pool = new HashMap<String, UserInfo>();
public static UserInfo getUserInfo(String key) {
UserInfo result = null;
if (!pool.containsKey(key)) {
result = new UserInfoPool(key);
pool.put(key, result);
} else {
System.out.print("从池中获取对象," + key);
result = pool.get(key);
}
return result;
}
}
准备好后,我们来看下我们的测试
public class Client {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
String key = "age" + i;
UserInfoFactory.getUserInfo(key);
}
UserInfoFactory.getUserInfo("age" + 92);
}
}
类图
后记
把享元模型
和解释器
放到最后,因为以前项目没有写过,不熟悉,查看了不少文章和书籍记录资料,都没有那个解释彻底的很明白的,对他的使用也不是很清晰,看到的有淘宝的主题的案例,记事本的文字等。但有些逻辑上的细节并不是很能自圆其说。所以这个一直拖着到这里。
现在的这个案例也不算很好,但暂时先写着,放在这里,那天有新的感觉了,再来更新。
但感觉这个享元在高并发的情况下还是会有用处的,保存一些公共的内容,降低对象的生成,节约内存。