每天一篇文章到了第18天,感覺越來越難沒什麼靈感(輸入不夠?),有一點點力不從心的感覺XD,專案要準備結案~還有鐵人賽的文章和各種活動(?)要參加,蠟燭三頭燒的感覺,但是希望都還是可以顧得到一定程度啊。
昨天談了備忘錄模式,對於需要在記憶體中紀錄資訊,並且後悔的狀況,可以有一個很好的解決。今天介紹的輕量模式,在大量物件需要創建時,藉由分享的方式避免重複創建(將已創建的物件記錄起來、並在要使用的時候取出),可以減少創建不必要的物件,達到所謂輕量化
的結果。
享元模式( Flyweight ),運用共有技術有效的支援大量細粒度的物件。
-- 大話設計模式 p393
有分為可以共享的資料和不能共享的資料,可以共享的資料稱為內部狀態,不能共享的資料稱為外部狀態。
macbook的產品有很多種,用享元模式(輕量模式),同樣的macbook實體只實體化一次
共有資料
public class Monitor {
private final String monitor = "Retina Display";
public String getMonitor() {
return monitor;
}
}
外部資料
//ExtrinsicState
public class CustomSetting {
//儲存一些使用者設定的類別
public static CustomSetting LOW = new CustomSetting("LOW");
public static CustomSetting HIGH = new CustomSetting("HIGH");
private String cpu;
private int memory;
private int storage;
public CustomSetting(){}
private CustomSetting(String set){
switch (set){
case "LOW":
// 一些低階設定
cpu = "i5";
memory = 8;
storage = 256;
break;
case "HIGH":
// 一些高階設定
cpu = "i7";
memory = 16;
storage = 512;
break;
default:
break;
}
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
public int getStorage() {
return storage;
}
public void setStorage(int storage) {
this.storage = storage;
}
@Override
public String toString() {
return "CustomSetting = { " + "\n" +
"cpu = " + this.getCpu() + "\n" +
"memory = " + this.getMemory() + "\n" +
"storage = " + this.getStorage() + "\n" +
"}";
}
}
Macbook 類別
public class Macbook extends Monitor{
enum Spec {
LOW ( CustomSetting.LOW ) , HIGH ( CustomSetting.HIGH );
CustomSetting customSetting;
Spec(CustomSetting customSetting){
this.customSetting = customSetting;
}
public CustomSetting getCustomSetting() {
return customSetting;
}
}
private CustomSetting customSetting;
public Macbook(Spec spec){
this.customSetting = spec.getCustomSetting();
}
public Macbook(CustomSetting customSetting){
this.customSetting = customSetting;
}
public void setCustomSetting(CustomSetting customSetting){
this.customSetting = customSetting;
}
@Override
public String toString() {
return "CustomSetting = { " + "\n" +
"cpu = " + customSetting.getCpu() + "\n" +
"memory = " + customSetting.getMemory() + "\n" +
"storage = " + customSetting.getStorage() + "\n" +
"monitor = " + getMonitor() + "\n" +
"}";
}
}
享元模式的Macbook Factory
import java.util.HashMap;
public class MacbookFactory {
private HashMap<CustomSetting,Macbook> cache = new HashMap();
public Macbook getCustomMacbook(CustomSetting key){
if(cache.containsKey(key)){
return cache.get(key);
}
Macbook macbook = new Macbook(key);
cache.put(key,macbook);
return macbook;
}
public Macbook getMacbook(Macbook.Spec spec){
if(cache.containsKey(spec.getCustomSetting())){
return cache.get(spec.getCustomSetting());
}
Macbook macbook = new Macbook(spec);
cache.put(spec.getCustomSetting(),macbook);
return macbook;
}
}
Test
public class Test {
@org.junit.jupiter.api.Test
public void test(){
MacbookFactory factory = new MacbookFactory();
Macbook goodbook = factory.getMacbook(Macbook.Spec.HIGH);
System.out.println(goodbook.toString());
CustomSetting superSetting = new CustomSetting();
superSetting.setCpu("i9");
superSetting.setMemory(32);
superSetting.setStorage(1024);
Macbook superMacbook = factory.getCustomMacbook(superSetting);
System.out.println(superMacbook.toString());
}
}
結果
CustomSetting = {
cpu = i7
memory = 16
storage = 512
monitor = Retina Display
}
CustomSetting = {
cpu = i9
memory = 32
storage = 1024
monitor = Retina Display
}
享元模式的分享就到這裡囉~有什麼問題歡迎提點小弟一下、感恩!