設(shè)計模式-享元

設(shè)計模式(Design pattern)是一套被反復(fù)使用让腹、多數(shù)人知曉的焦读、經(jīng)過分類編目的仓蛆、代碼設(shè)計經(jīng)驗的總結(jié)。GoF提出了23種設(shè)計模式蝌诡,本系列將使用Swift語言來實現(xiàn)這些設(shè)計模式

概述

通過共享已存在的對象溉贿,減少創(chuàng)建對象內(nèi)存開銷的設(shè)計模式被稱作享元模式

享元模式Flyweight和單例模式Singleton像是一對孿生兄弟,二者的表現(xiàn)方式非常相似浦旱,但二者的存在目的卻不一樣:

  • 單例模式
    保證了整個應(yīng)用聲明周期內(nèi)顽照,同一個對象只會存在一份內(nèi)存,并且任何時間都能被訪問使用。


  • 享元模式
    如果存在可以復(fù)用的對象代兵,那么對象將被共享而不是創(chuàng)建新的對象


在iOS開發(fā)中尼酿,享元模式的最佳實踐就是UITableView的復(fù)用機制——超出屏幕外的單元格統(tǒng)一被回收放到一個復(fù)用隊列之中,等待著需要新的單元格時進行復(fù)用植影。

實戰(zhàn)

筆者最近項目有一個需求裳擎,幾乎所有的數(shù)據(jù)都要保存在本地。由于應(yīng)用的特殊性思币,模塊之間需要用到彼此的數(shù)據(jù)鹿响,如果使用單例模式來做,那么同一時間占用的內(nèi)存是非常的大的谷饿,因此以享元模式的思想封裝了一個數(shù)據(jù)管理類:

class DataManager {
    //MARK: - Variable
    private static var shareStorage = [String: AnyObject]()
    private var storeKey = "DefaultKey"
    private var storeData = [AnyObject]()
    var data: [AnyObject] {
        get {
            return storeData
        }
    }

    //MARK: - Operate
    func insert(data: AnyObject) { }
    func delete(at index: Int) { }
    func save() { }
}

筆者以數(shù)據(jù)模型的類名作為數(shù)據(jù)管理的關(guān)鍵字惶我,因此創(chuàng)建一個私有的靜態(tài)字典用來保存當(dāng)前正在使用的數(shù)據(jù)。由于數(shù)據(jù)以加密的方式存儲在沙盒目錄下博投,在數(shù)據(jù)量足夠大的時候绸贡,從本地讀取這些數(shù)據(jù)會占用大量的花銷,因此在數(shù)據(jù)管理對象被創(chuàng)建的時候需要判斷是否存在可復(fù)用的數(shù)據(jù)毅哗,如果不存在再從本地加載:

class DataManager {
    init() {
        initalizeData()
    }

    init(storeKey: String) {
        self.storeKey = storeKey
        initalizeData()
    }

    private func initalizeData() {
        if let data = DataManager.shareStorage[storeKey] {
            storeData = data as! [AnyObject]
        } else {
            loadData()
            DataManager.shareStorage[storeKey] = storeData as AnyObject?
        }
    }

    private func loadData() {
        //  load data from local path
    }
}

ok听怕,對于數(shù)據(jù)的復(fù)用已經(jīng)完成了,剩下的問題是不可能讓字典一直存儲這些數(shù)據(jù)虑绵,否則直接使用單例要更加方便的多尿瞭。對此,筆者使用了計數(shù)功能翅睛,保證數(shù)據(jù)可以在沒有使用的時候進行本地存儲然后釋放:

class DataManager {

    deinit {
        let count = DataManager.shareStorage[countKey()] as! Int
        if count == 1 {
            save()
            DataManager.shareStorage[storeKey] = nil
        } else {
            DataManager.shareStorage[countKey()] = (count - 1) as AnyObject?
        }
    }

    private func initalizeData() {
        if let data = DataManager.shareStorage[storeKey] {
            let count = DataManager.shareStorage[countKey()] as! Int
            DataManager.shareStorage[countKey()] = (count + 1) as AnyObject?
            storeData = data as! [AnyObject]
        } else {
            loadData()
            DataManager.shareStorage[countKey()] = 1 as AnyObject
            DataManager.shareStorage[storeKey] = storeData as AnyObject?
        }
    }

    private func countKey() -> String {
        return "\(storeKey)Count"
    }
}

上面的代碼是初步的邏輯搭建声搁,下一步還需要考慮線程安全等其他問題,這里就不再寫出來了

總結(jié)

最開始接觸享元模式概念的時候捕发,筆者是有些混亂的疏旨,也不清楚它和單例的區(qū)別。簡單來說爬骤,這是一種提供了一種擁有單例優(yōu)點、以及改善了一部分單例缺點的設(shè)計模式莫换,但是享元模式更加的復(fù)雜霞玄,在考慮到多線程的環(huán)境下,數(shù)據(jù)競爭要比單例激烈的多拉岁,也危險的多坷剧。

上一篇:Swift實戰(zhàn)-單例模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市喊暖,隨后出現(xiàn)的幾起案子惫企,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狞尔,死亡現(xiàn)場離奇詭異丛版,居然都是意外死亡,警方通過查閱死者的電腦和手機偏序,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門页畦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人研儒,你說我怎么就攤上這事豫缨。” “怎么了端朵?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵好芭,是天一觀的道長。 經(jīng)常有香客問我冲呢,道長舍败,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任碗硬,我火速辦了婚禮瓤湘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恩尾。我一直安慰自己弛说,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布翰意。 她就那樣靜靜地躺著木人,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冀偶。 梳的紋絲不亂的頭發(fā)上醒第,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音进鸠,去河邊找鬼稠曼。 笑死,一個胖子當(dāng)著我的面吹牛客年,可吹牛的內(nèi)容都是我干的霞幅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼量瓜,長吁一口氣:“原來是場噩夢啊……” “哼司恳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起绍傲,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤扔傅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猎塞,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡试读,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了邢享。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹏往。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖骇塘,靈堂內(nèi)的尸體忽然破棺而出伊履,到底是詐尸還是另有隱情,我是刑警寧澤款违,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布唐瀑,位于F島的核電站,受9級特大地震影響插爹,放射性物質(zhì)發(fā)生泄漏哄辣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一赠尾、第九天 我趴在偏房一處隱蔽的房頂上張望力穗。 院中可真熱鬧,春花似錦气嫁、人聲如沸当窗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崖面。三九已至,卻和暖如春梯影,著一層夾襖步出監(jiān)牢的瞬間巫员,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工甲棍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留简识,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓感猛,卻偏偏與公主長得像七扰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子唱遭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容