1. 程式人生 > >Android設計模式系列(6)--SDK原始碼之享元模式

Android設計模式系列(6)--SDK原始碼之享元模式

享元模式,給我的感覺就是物件池,快取單例物件。
java中的享元模式最經典的例子就是String類了,還有一個最容易理解的就是word文件字元共享的例子,也是享元模式的經典應用。
本文對android中的sql編譯類SQLiteCompiledSql說明,展開分析,也是很容易理解的一個例子,其實,android SDK中必然有很多地方需要用到享元模式。
享元模式,Flyweight  Pattern,說的嚴重點,一些程式如果不使用享元模式的話,根本不能使用面向物件的方法實現,物件會多的撐爆你的記憶體:"用面向物件思想設計的應用常常會面臨物件例項過多的問題"。 

1.意圖
運用共享技術有效地支援大量細粒度的物件。
熱門詞彙:共享 池 快取 內部狀態 外部狀態 物件 單例

 

2.結構 


這是一個完整的享元模式結構圖。
客 戶端通過享元工廠獲取享元物件,享元物件的建立則根據工廠的享元池來控制,如果有享元池中沒有這個物件,則建立這個物件並儲存到享元池中,如果享元池中有 這個物件,則直接使用這個物件。因為享元物件在共享的同時,說明它重用屬性的不變性,不然都是變化的東西,不存在共享,這些不變得屬性我們稱之為內部狀 態,獨立與外部場景。而另外一些屬性,可以根據外部場景變化的,我們稱之為外部狀態,在上圖中我們也看到,我們可以通過Operation改變外部狀態。
Android 中SQLiteCompiledSql的使用,其實是很多資料庫系統典型的實現。從應用啟動,通過各種資料庫操作,我們不知道進行了多少次的查詢操作,而 這些操作中又有相當一部分sql語句是相同的,這些編譯後的sql編譯物件其實是一樣的,是可以共用共享的,其實就是快取。 SQLiteCompiledSql就是這樣的一個需要共享的享元物件,畫出相關的UML圖如下:


其中SqliteDatabase中的mCompiledQuerie就是存放享元物件的容器。
通過這種方式大大減少了sql編譯物件的建立,提高了資料庫操作的效能。

3.程式碼
享元物件類SQLiteCompiledSql,主要是內部狀態sql語句:

class SQLiteCompiledSql {
    private String mSqlStmt = null;
    native_compile(sql);
    native_finalize();
}

享元工廠類:

public class SQLiteDatabase{
     Map<String, SQLiteCompiledSql> mCompiledQueries = Maps.newHashMap();
     SQLiteCompiledSql getCompiledStatementForSql(String sql) {
        SQLiteCompiledSql compiledStatement = null;
        boolean cacheHit;
        synchronized(mCompiledQueries) {
            if (mMaxSqlCacheSize == 0) {
                return null;
            }
            cacheHit = (compiledStatement = mCompiledQueries.get(sql)) != null;
        }
        if (cacheHit) {
            mNumCacheHits++;
        } else {
            mNumCacheMisses++;
        }
        return compiledStatement;
    }
 
    private void deallocCachedSqlStatements() {
        synchronized (mCompiledQueries) {
            for (SQLiteCompiledSql compiledSql : mCompiledQueries.values()) {
                compiledSql.releaseSqlStatement();
            }
            mCompiledQueries.clear();
        }
    }
 
    void addToCompiledQueries(String sql, SQLiteCompiledSql compiledStatement) {
         //省略具體程式碼
    }
}

  其他類幾個相關類是對這個集合的操作相關,和享元模式沒有什麼實質性的關係,程式碼省略。

4.效果
(1).結構型模式;
(2).節約儲存的方法:用共享減少內部狀態的消耗,用計算時間換取對外部狀態的儲存;
(3).緩衝。