設計模式--享元模式

Java工程源碼

類圖

這裏寫圖片描述


定義
使用共享對象可有效地支持大量的細粒度的對象


優點
- 大大減少應用程序創建的對象,降低程序內存的佔用,增強程序的性能

缺點
- 提高了系統的複雜性,需要分離出外部狀態和內部狀態


使用場景
- 系統中存在大量相似對象
- 細粒度的對象都具備較接近的外部狀態,且內部狀態與環境無關
- 需要緩衝池的場景


注意事項
外部狀態最好以java基本類型(int,string等)作爲標誌,可以大幅提高效率。
如果把一個對象作爲鍵值,一定要確保重寫了equals和hashcode方法。
關於對象池和享元模式的區別,對象池着重在對象的複用上,池中的每個對象是可替換的,
從同一個池中獲得A對象和B對象對客戶端來說是完全相同的,它主要解決服用,
而享元模式主要解決的是對象的共享問題,如何建立多個可共享的細粒度對象則是其關注的重點


抽象享元角色

public abstract class FlyWeight {
    private String intrinsic;
    protected final String extrinsic;

    public FlyWeight(String _extrinsic) {
        this.extrinsic = _extrinsic;
    }

    /**
     * 定義業務操作
     */
    public abstract void operate();

    // 內部狀態的getter和setter
    public String getIntrinsic() {
        return intrinsic;
    }

    public void setIntrinsic(String intrinsic) {
        this.intrinsic = intrinsic;
    }
}

具體享元角色

public class ConcreteFlyWeight extends FlyWeight {

    /**
     * @param _extrinsic
     */
    public ConcreteFlyWeight(String _extrinsic) {
        super(_extrinsic);
    }

    /**
     * 根據外部狀態進行邏輯處理
     */
    @Override
    public void operate() {
        System.out.println("ConcreteFlyWeight->" + extrinsic);
        System.out.println("ConcreteFlyWeight->" + getIntrinsic());
    }
}

享元工廠

public class FlyWeightFactory {
    private static HashMap<String, FlyWeight> pool = new HashMap<>();

    public static FlyWeight getFlyWeight(String extrinsic) {
        FlyWeight flyWeight;
        if (pool.containsKey(extrinsic)) {
            flyWeight = pool.get(extrinsic);
        } else {
            flyWeight = new ConcreteFlyWeight(extrinsic);
            pool.put(extrinsic, flyWeight);
        }
        return flyWeight;
    }
}

場景類

public class Client {
    public static void main(String[] args) {
        // fw1和fw2共享了同一個對象
        FlyWeight fw1 = FlyWeightFactory.getFlyWeight("name 1");
        fw1.setIntrinsic("fw1");
        fw1.operate();
        FlyWeight fw2 = FlyWeightFactory.getFlyWeight("name 1");
        fw2.setIntrinsic("fw2");
        fw2.operate();
        // fw3使用了一個新對象
        FlyWeight fw3 = FlyWeightFactory.getFlyWeight("name 3");
        fw3.setIntrinsic("fw3");
        fw3.operate();
    }
}

運行結果

ConcreteFlyWeight->name 1
ConcreteFlyWeight->fw1
ConcreteFlyWeight->name 1
ConcreteFlyWeight->fw2
ConcreteFlyWeight->name 3
ConcreteFlyWeight->fw3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章