在工厂模式的代码中,我们不停的生成的对象,每个对象都是全新的,并在占用了部分的内存,而往往很多的对象内容都是相同的,也就是说可以共用的。享元模式也正是为了解决这种资源上的浪费而提出来的。
那么怎么样才能做到共享细粒度的对象呢?参考GoF提供的图片:
其中我觉得最关键的就是享元工厂角色中HashMap,他保存了每个实例化后的对象并使用key-value的形式保存起来。当遇到相同的key时候,直接获取内存的对象,而不用再重新创建。
图中可以这样被重复使用的就是享元角色,而没有参与参与对象保存的就是非享元角色。这样的形式是否很类似Java项目中Session之类呢。看如下代码:
//享元工厂角色
package com.henry.designModel.flyweight;
import java.util.HashMap;
import java.util.Map;
public class SessionFactory {
private Map<String, Session> sessions = new HashMap<>();
public Session getSession(String key) {
Session session = sessions.get(key);
if(session == null) {
System.out.println("未存在,创建新的");
session = new ObjectSession(key);
sessions.put(key, session);
} else {
System.out.println("已存在,直接使用");
}
return session;
}
public void setSessions(HashMap<String, Session> sessions) {
this.sessions = sessions;
}
}
//享元角色抽象
package com.henry.designModel.flyweight;
public interface Session {
public User getUser(String name);
}
//具体享元角色
package com.henry.designModel.flyweight;
public class ObjectSession implements Session {
private String key;
public ObjectSession(String key) {
this.key = key;
}
@Override
public User getUser(String name) {
System.out.println("获取" + name + "对象");
return new User(name);
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
//非享元角色
package com.henry.designModel.flyweight;
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//客户类
package com.henry.designModel.flyweight;
public class Client {
public static void main(String[] args) {
SessionFactory factory = new SessionFactory();
Session session0 = factory.getSession("a");
Session session1 = factory.getSession("a");
Session session2 = factory.getSession("a");
User user0 = session0.getUser("henry");
User user1 = session1.getUser("ivy");
User user2 = session2.getUser("theodore");
}
}
执行客户类的结果如下:
在第二次和第三次的session获取操作中,已经不再创建新的session对象了。
欢迎使用haptool.com(哈普工具),让程序员的工作更有效率。