設計模式學習筆記——享元(Flyweight)模式
@(設計模式)[設計模式, 享元模式, flyweight]
基本介紹
享元模式適用於需要new
大量對象的情況。通過共享實例的方式避免new
出實例,浪費資源。
在使用享元模式的時候要注意,當共享實例修改時,將會影響使用該實例的多處地方,所以使用前需要斟酌,什麼類需要使用享元模式。
享元案例
類圖
實現代碼
BigChar類
package com.pc.flyweight.example;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* 大字符類
* Created by Switch on 2017/3/31.
*/
public class BigChar {
/**
* 字符名稱
*/
private char charname;
/**
* 大型字符對應的字符串(由'#' '.' '\n'組成)
*/
private String fontdata;
/**
* 構造方法,設置字符名稱,並初始化數據
*
* @param charname 字符名稱
*/
public BigChar(char charname) {
this.charname = charname;
try {
BufferedReader reader = new BufferedReader(new FileReader(System.getProperty("user.dir")
+ "/src/main/java/com/pc/flyweight/example/char/big" + charname + ".txt"));
String line;
StringBuffer buf = new StringBuffer();
while ((line = reader.readLine()) != null) {
buf.append(line);
buf.append("\n");
}
reader.close();
this.fontdata = buf.toString();
} catch (IOException e) {
this.fontdata = charname + "?\n";
}
}
/**
* 顯示大型字符
*/
public void print() {
System.out.print(fontdata);
}
}
BigCharFactory類
package com.pc.flyweight.example;
import java.util.HashMap;
import java.util.Map;
/**
* 大字符工廠類
* Created by Switch on 2017/3/31.
*/
public final class BigCharFactory {
/**
* 管理已經生成的BigChar的實例
*/
private Map<String, BigChar> pool = new HashMap<>();
/**
* 唯一實例
*/
private static BigCharFactory instance = new BigCharFactory();
/**
* 獲取實例
*
* @return 實例
*/
public static BigCharFactory getInstance() {
return instance;
}
private BigCharFactory() {
}
/**
* 生成(共享)BigChar類的實例
*
* @param charname 字符名
* @return 大字符對象
*/
public synchronized BigChar getBigChar(char charname) {
BigChar bc = pool.get("" + charname);
if (bc == null) {
bc = new BigChar(charname);
pool.put("" + charname, bc);
}
return bc;
}
}
BigString類
package com.pc.flyweight.example;
/**
* 大字符串
* Created by Switch on 2017/3/31.
*/
public class BigString {
/**
* 大字符數組
*/
private BigChar[] bigChars;
/**
* 構造方法,傳入字符串
*
* @param string 字符串
*/
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();
}
}
}
測試類
package com.pc.flyweight.example.test;
import com.pc.flyweight.example.BigString;
import org.junit.Test;
/**
* BigString Tester.
*
* @author Switch
* @version 1.0
*/
public class BigStringTest {
/**
* 測試享元模式
*/
@Test
public void testBigString() {
BigString bigString = new BigString("123-456.");
bigString.print();
}
}
運行結果
......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................
....######......
..##......##....
..........##....
......####......
....##..........
..##............
..##########....
................
....######......
..##......##....
..........##....
......####......
..........##....
..##......##....
....######......
................
................
................
................
................
..##########....
................
................
................
........##......
......####......
....##..##......
..##....##......
..##########....
........##......
......######....
................
..##########....
..##............
..##............
..########......
..........##....
..##......##....
....######......
................
....######......
..##......##....
..##............
..########......
..##......##....
..##......##....
....######......
................
.?
享元模式中的角色
Flyweight(輕量級)
按照通常方式編寫程序會導致程序變重,所以如果能夠共享實例會比較好,而Flyweight
角色表示的就是那些實例會被共享的類。在案例中,由BigChar
類扮演此角色。
FlyweightFactory(輕量級工廠)
FlyweightFactory
角色是生成Flyweight
角色的工廠。在工廠中生成Flyweight
角色可以實現共享實例。在案例中,由BigCharFactory
類扮演此角色。
Client(請求者)
Client
角色使用FlyweightFactory
角色來生成Flyweight
角色。在案例中,由BigString
類扮演此角色。
類圖
GitHub:DesignPatternStudy
——————參考《圖解設計模式》