1. 程式人生 > >設計模式——享元模式

設計模式——享元模式

.post 運行時間 AD 重復 this com 本地 方式 sign

享元模式定義

復用內存中已經存在的對象,降低重復創建對象的性能消耗。

享元模式 UML圖

技術分享圖片

享元共享技術

享元中內部狀態時共享的,Flyweight factory負責維護一個對象池(Flyweight pool)。細粒度的對象和共享對象,當我們分配太多的對象到應用程序中將有損程序的性能,同時還容易造成內存溢出。要避免這個問題的方式,就是享元模式提到的共享技術。

內部狀態和外部狀態

  • 內部狀態
    內部狀態是對象可共享出來的信息,存儲在享元對象內部並且不會隨環境改變的改變。
  • 外部狀態
    外部狀態時對象得以依賴的標記,是隨環境改變而改變的,不可以共享的狀態。

享元角色

  • Flyweight
    是一個產品的抽象類,同時定義出對象的外部狀態和內部狀態的接口或實現。
  • ConcreteFlyweight
    具體的一個產品類,實現抽象角色定義業務,該角色中需要註意的是內部狀態處理應該與環境無關,不應該出現一個操作改變了內部狀態,同時修改了外狀態,這是絕對不允許的。
  • unshareConcreteFlyweight
    不存在外部狀態或者安全要求(線程安全)不能夠使用共享技術的對象,該對象一般不會出現在享元工廠中。
  • FlyweightFactory
    職責非常簡單,就是構造一個池容器,同時提供從池中獲得對象的方法。

享元模式的意義

享元模式的目的在於運用共享技術,使得一些細粒度的對象可以共享,多使用細粒度對象便於重構。

享元模式例子

     private String id;

    private String location;

    private String subject;

    private String postAddress;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getPostAddress() {
        return postAddress;
    }

    public void setPostAddress(String postAddress) {
        this.postAddress = postAddress;
    }
    public class SignInfo4Pool extends SignInfo{

    //定義一個對象池提取的KEY值
    private String key;

    //構造函數獲取相同標誌
    public SignInfo4Pool(String key) {
        this.key = key;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
    public class SignInfoFactory {

    private static HashMap<String, SignInfo> pool = new HashMap<String, SignInfo>();

    public static SignInfo getSignInfo(String key) {
        SignInfo result = null;

        //
        if (!pool.containsKey(key)) {
            System.out.println(key + "創建對象,放入池中");
            result = new SignInfo4Pool(key);
        } else {
            result = pool.get(key);
            System.out.println("獲取key" + key);
        }
        return result;
    }
}

享元模式使用場景

1、當我們發現某個類型的對象有大量的實例時,我們是否可以對這些實例進行分類,經過分類後,我們發現只有很少的類別的情況下。
2、我們發現通過使用享元模式後能夠提高系統的性能和不會帶來更多的復雜度時。
享元模式一般是給出本地內存資源節省的一個方案,並不適合互聯網上的分布式應用的情況,不過享元模式對於排他性的要求資源的控制,是個不
錯的選擇。

優點

1、享元模式的優點在於它能夠極大的減少系統中對象的個數。
2、享元模式由於使用了外部狀態,外部狀態相對獨立,不會影響到內部狀態,所以享元模式使得享元對象能夠在不同的環境被共享。

缺點

1、由於享元模式需要區分外部狀態和內部狀態,使得應用程序在某種程度上來說更加復雜化了。
2、為了使對象可以共享,享元模式需要將享元對象的狀態外部化,而讀取外部狀態使得運行時間變長。

設計模式——享元模式