1、引入
flyweight,从字面意思来看,可以飞的质量,这么来说是很轻了,它的译义也为轻量级。
在程序设计中,往往有这样一种对象,它在某个场景下大量被使用,如果一种通过new的方式创建的话,会导致大量的内存占用。
而flyweight模式,正是通过尽量共享对象的方式来减少资源的浪费。
2、示例
有这样一种大字符类,其通过多个小字符组成图像,如下:
如果在使用它们的时候频繁创建,那么会占用大量资源,因此在这里使用flyweight模式。
2.2.1、BigChar类
public class BigChar {
private char charName;
private String fontData;
public BigChar(char charName) {
this.charName = charName;
try {
BufferedReader reader = new BufferedReader(new FileReader(
"./src/flyweight/example/big" + charName + ".txt" //通过txt存储
));
String line;
StringBuffer buffer = new StringBuffer();
while ((line = reader.readLine()) != null) {
buffer.append(line);
buffer.append("\n");
}
reader.close();
this.fontData=buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
public void print() {
System.out.println(fontData);
}
}
2.2、BigCharFactory类
通过单例的工厂操作BigChar,实现资源共享
public class BigCharFactory {
private HashMap pool=new HashMap<Character,BigChar>();
private static BigCharFactory singleton=new BigCharFactory();
private BigCharFactory() {
}
public static BigCharFactory getInstance() {
return singleton;
}
public synchronized BigChar getBigChar(char charName) {
BigChar bigChar = (BigChar)pool.get(charName);
if (bigChar == null) {
bigChar=new BigChar(charName);
pool.put(charName, bigChar);
}
return bigChar;
}
}
2.3、BigString类
将string对象转化为BigChar的类
public class BigString {
private BigChar[] bigChars;
public BigString(String str) {
BigCharFactory bigCharFactory = BigCharFactory.getInstance();
bigChars=new BigChar[str.length()];
for (int i = 0; i < bigChars.length; i++) {
bigChars[i]=bigCharFactory.getBigChar(str.charAt(i));
}
}
public void print() {
for (int i = 0; i < bigChars.length; i++) {
bigChars[i].print();
}
}
}
2.4、测试
public class Main {
public static void main(String[] args) {
BigString bigString = new BigString("12");
bigString.print();
}
}
运行结果:
3、tips
- flyweight模式的应用要求在一处地方修改对象不能影响别处,因为是共享的对象。
- 在本例中采用的池化技术,在许多地方也有用到,是flyweight模式的体现,如:
- 字符串常量池
- 数据库连接池
- 包装类Integer的cache池
- etc