背景
享元模式又叫做 FlyWeight 模式,一言以蔽之就是“通过尽量共享实例来避免 new 出实例”,当需要某个实例时,并不总是通过new 关键字来生成实例,而是尽量共用已经存在的实例。
登场角色
Flyweight 轻量级
按照通常方式编写程序会导致程序变重,所以如果可以能够共享实例会比较好,而Flyweight表示的就是那些实例会被共享的类;
FlyweightFactory 轻量级工厂
FlyweightFactory 角色是生成Flyweight 角色的工厂,在工厂中生成Flyweight 角色可以实现共享实例;
Client 请求者
Client 角色使用 FlyweightFactory 角色来生成 Flyweight 角色;
类图
示例代码
实例是一个显示特殊字符串的代码,将每个不同的字符先保存起来,根据字符串中不同的字符从Factory获取即可,不必每次都创建;
BigChar
public class BigChar {
private char charName;
private String fontdata;
public BigChar(char charName) {
this.charName = charName;
try {
String line;
BufferedReader bufferedReader = new BufferedReader(new FileReader(charName + ".txt"));
StringBuffer stringBuffer = new StringBuffer();
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line);
stringBuffer.append("\n");
}
bufferedReader.close();
fontdata = stringBuffer.toString();
} catch (IOException e) {
fontdata = charName + "?";
}
}
public void print() {
System.out.println(fontdata);
}
}
BigCharFactory
public class BigCharFactory {
private HashMap<String, BigChar> pool = new HashMap<>();
private static BigCharFactory singleton = new BigCharFactory();
public static BigCharFactory getInstance() {
return singleton;
}
private BigCharFactory() {
}
public BigChar getBigChar(char charName) {
BigChar bigChar = pool.get(charName + "");
if (bigChar == null) {
bigChar = new BigChar(charName);
pool.put(charName + "", bigChar);
}
return bigChar;
}
}
BigString
public class BigString {
private BigChar[] bigChars;
public BigString(String string) {
char[] chars = string.toCharArray();
int length = chars.length;
bigChars = new BigChar[length];
for (int i = 0; i < chars.length; i++) {
bigChars[i] = BigCharFactory.getInstance().getBigChar(chars[i]);
}
}
public void print() {
for (int i = 0; i < bigChars.length; i++) {
bigChars[i].print();
}
}
}
功能分析
- 在决定 Flyweight 角色中的字段时,需要精挑细选,只将那些真正应该在多个地方共享的字段定义在 Flyweight 角色中即可;
- 不要让垃圾回收器把 共享实例 回收掉,因为 pool 字段一直管理着这些共享角色,一直引用着他们,不会被垃圾回收器回收;
- 可以减少内存的使用量,减少生成实例所花费的时间;