1. 程式人生 > 其它 >零基礎學程式設計034:解決一個pandas問題

零基礎學程式設計034:解決一個pandas問題

  1 享元模式
  定義:通過共享的方式高效的支援大量細粒度的物件。

  主要解決:在有大量物件時,有可能會造成記憶體溢位,我們把其中共同的部分抽象出來,如果有相同的業務請求,直接返回在記憶體中已有的物件,避免重新建立。

  何時使用: 1、系統中有大量物件。 2、這些物件消耗大量記憶體。 3、這些物件的狀態大部分可以外部化。 4、這些物件可以按照內蘊狀態分為很多組,當把外蘊物件從物件中剔除出來時,每一組物件都可以用一個物件來代替。 5、系統不依賴於這些物件身份,這些物件是不可分辨的。

  如何解決:用唯一標識碼判斷,如果在記憶體中有,則返回這個唯一標識碼所標識的物件。

  關鍵程式碼:用 HashMap 儲存這些物件。

  應用例項: 1、JAVA 中的 String,如果有則返回,如果沒有則建立一個字串儲存在字串快取池裡面。

  優點:大大減少物件的建立,降低系統的記憶體,使效率提高。

  缺點:提高了系統的複雜度,需要分離出外部狀態和內部狀態,而且外部狀態具有固有化的性質,不應該隨著內部狀態的變化而變化,否則會造成系統的混亂。

  簡單來說,我們抽取出一個物件的外部狀態(不能共享)和內部狀態(可以共享)。然後根據外部狀態的決定是否建立內部狀態物件。內部狀態物件是通過雜湊表儲存的,當外部狀態相同的時候,不再重複的建立內部狀態物件,從而減少要建立物件的數量。

  1.1 享元模式的結構圖和程式碼示例

 


  1、Flyweight (享元抽象類):一般是介面或者抽象類,定義了享元類的公共方法。這些方法可以分享內部狀態的資料,也可以呼叫這些方法修改外部狀態。

  2、ConcreteFlyweight(具體享元類):具體享元類實現了抽象享元類的方法,為享元物件開闢了記憶體空間來儲存享元物件的內部資料,同時可以通過和單例模式結合只建立一個享元物件。

  3、FlyweightFactory(享元工廠類):享元工廠類建立並且管理享元類,享元工廠類針對享元類來進行程式設計,通過提供一個享元池來進行享元物件的管理。一般享元池設計成鍵值對,或者其他的儲存結構來儲存。當客戶端進行享元物件的請求時,如果享元池中有對應的享元物件則直接返回對應的物件,否則工廠類建立對應的享元物件並儲存到享元池。

  舉例(JAVA 中的 String,如果有則返回,如果沒有則建立一個字串儲存在字串快取池裡面)。類圖如下:

 

 

  (1)建立享元物件介面

    public interface IFlyweight {
      void print();
    }
  (2)建立具體享元物件

    public class Flyweight implements IFlyweight {
      private String id;
      public Flyweight(String id){
        this.id = id;
      }
      @Override
      public void print() {
        System.out.println("Flyweight.id = " + getId() + " ...");
      }
      public String getId() {
        return id;
      }
    }
  (3)建立工廠,這裡要特別注意,為了避免享元物件被重複建立,我們使用HashMap中的key值保證其唯一。

    public class FlyweightFactory {
      private Map<String, IFlyweight> flyweightMap = new HashMap();
      public IFlyweight getFlyweight(String str){
        IFlyweight flyweight = flyweightMap.get(str);
        if(flyweight == null){
          flyweight = new Flyweight(str);
          flyweightMap.put(str, flyweight);
        }
        return flyweight;
      }
      public int getFlyweightMapSize(){
        return flyweightMap.size();
      }
    }
  (4)測試,我們建立三個字串,但是隻會產生兩個享元物件

    public class MainTest {
      public static void main(String[] args) {
        FlyweightFactory flyweightFactory = new FlyweightFactory();
        IFlyweight flyweight1 = flyweightFactory.getFlyweight("A");
        IFlyweight flyweight2 = flyweightFactory.getFlyweight("B");
        IFlyweight flyweight3 = flyweightFactory.getFlyweight("A");
        flyweight1.print();
        flyweight2.print();
        flyweight3.print();
        System.out.println(flyweightFactory.getFlyweightMapSize());
      }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           }