每天一篇文章到了第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
}
享元模式的分享就到這裡囉~有什麼問題歡迎提點小弟一下、感恩!