一、什麼是Flyweight模式
Flyweight,是輕量級的意思,Flyweight模式旨在使得類的建立、使用變得簡便。如何實作呢?在一般的程式設計裡面,想要使用一個對象,會通過new的方式建立,那麼每一個地方需要使用該對象,就要new一次,在計算機記憶體中則需要每次都要配置設定記憶體空間出來,當使用new的次數增多時,記憶體空間也随着消耗加大。Flyweight模式則是通過盡量共享執行個體來避免記憶體的大量消耗。
二、Flyweight模式的原理
Flyweight類:是一些需要被共享的類;
FlyweightFactory類:負責生成Flyweight類的工廠類;
Client類:調用類。
三、Flyweight模式執行個體
現在由一些由許多普通字元組合成為“大型字元”的類,它的執行個體就是重執行個體。示例中根據傳遞的數字,輸出對應的檔案内容。進行示例之前,要準備一些txt檔案。
本示例的txt檔案内容如下:
UML圖:
1、BigChar類
package com.cjs.Flyweight;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BigChar {
private final String PATH = "E:\\IntelliJ Idea\\designMode\\src\\main\\resources\\";
private char charName;
private String fontdata;
public BigChar(char charName) {
this.charName = charName;
try {
BufferedReader reader = new BufferedReader(new FileReader(PATH+"big" + charName + ".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 (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void print() {
System.out.println(fontdata);
}
}
BigChar類定義了三個屬性,PATH定義了檔案路徑,charName表示将要傳進來的字元,如‘1’,‘2’等等,fontdata用于存儲檔案内容,以及輸出。構造方法的作用是:根據傳進來的字元,找到對應的txt檔案,然後逐行讀取資訊,将資訊用StringBuffer對象儲存,最後一次性儲存在fontdata字元串中。
2、BigCharFactory類
package com.cjs.Flyweight;
import java.util.HashMap;
public class BigCharFactory {
private HashMap pool = new HashMap();
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;
}
}
因為BigCharFactory對象是共享的,隻需要一個,是以使用了單例模式,另外,該工廠類主要用于生産BigChar對象,是以定義了getBigChar方法,該方法作用是,先根據字元到pool裡面找,是否存在對應的對象,如果存在,直接傳回、使用BigChar對象,如果不存在,建立一個新的BigChar對象,并放在pool裡面。pool是一個HashMap類型屬性,使用鍵值對來管理BigChar對象。
3、BigString類
package com.cjs.Flyweight;
public class BigString {
private BigChar[] bigChars;
public BigString(String string) {
bigChars = new BigChar[string.length()];
BigCharFactory factory = BigCharFactory.getInstance();
for (int i = 0; i < bigChars.length; i++) {
bigChars[i] = factory.getBigChar(string.charAt(i));
}
}
public void print() {
for (int i = 0; i < bigChars.length; i++) {
bigChars[i].print();
}
}
}
BigString作用是根據傳入的字元串,将其拆分為單個字元,通過字元擷取對應的BigChar執行個體對象,逐個輸出。
4、Main類
package com.cjs.Flyweight;
public class Main {
public static void main(String[] args) {
BigString bigString = new BigString("12323");
bigString.print();
}
}
輸出結果:
四、總結
Flyweight模式核心在FlyweightFactory類的getFlyweight()方法的算法,什麼時候建立新對象,如何建立。值得注意的是,Flyweight模式思想是“共享”,換句話說,同一個執行個體對象,會被多個地方使用,當要改變被共享的對象時,就會有多個地方産生影響。