欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go設(shè)計(jì)模式之單例模式圖文詳解

 更新時(shí)間:2023年07月26日 08:30:12   作者:demo007x  
單例模式是一種創(chuàng)建型設(shè)計(jì)模式,讓你能夠保證一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)該實(shí)例的全局節(jié)點(diǎn),本文就通過(guò)圖文給大家介紹一下Go的單例模式,需要的朋友可以參考下

單例模式.

問(wèn)題

單例模式同時(shí)解決了兩個(gè)問(wèn)題, 所以違反了單一職責(zé)原則:

  • 保證一個(gè)類只有一個(gè)實(shí)例。 為什么會(huì)有人想要控制一個(gè)類所擁有的實(shí)例數(shù)量? 最常見(jiàn)的原因是控制某些共享資源 (例如數(shù)據(jù)庫(kù)或文件) 的訪問(wèn)權(quán)限。

    它的運(yùn)作方式是這樣的: 如果你創(chuàng)建了一個(gè)對(duì)象, 同時(shí)過(guò)一會(huì)兒后你決定再創(chuàng)建一個(gè)新對(duì)象, 此時(shí)你會(huì)獲得之前已創(chuàng)建的對(duì)象, 而不是一個(gè)新對(duì)象。

    注意, 普通構(gòu)造函數(shù)無(wú)法實(shí)現(xiàn)上述行為, 因?yàn)闃?gòu)造函數(shù)的設(shè)計(jì)決定了它必須總是返回一個(gè)新對(duì)象。

客戶端甚至可能沒(méi)有意識(shí)到它們一直都在使用同一個(gè)對(duì)象。

  • 為該實(shí)例提供一個(gè)全局訪問(wèn)節(jié)點(diǎn)。 還記得你 (好吧, 其實(shí)是我自己) 用過(guò)的那些存儲(chǔ)重要對(duì)象的全局變量嗎? 它們?cè)谑褂蒙鲜址奖悖?但同時(shí)也非常不安全, 因?yàn)槿魏未a都有可能覆蓋掉那些變量的內(nèi)容, 從而引發(fā)程序崩潰。

    和全局變量一樣, 單例模式也允許在程序的任何地方訪問(wèn)特定對(duì)象。 但是它可以保護(hù)該實(shí)例不被其他代碼覆蓋。

    還有一點(diǎn): 你不會(huì)希望解決同一個(gè)問(wèn)題的代碼分散在程序各處的。 因此更好的方式是將其放在同一個(gè)類中, 特別是當(dāng)其他代碼已經(jīng)依賴這個(gè)類時(shí)更應(yīng)該如此。

如今, 單例模式已經(jīng)變得非常流行, 以至于人們會(huì)將只解決上文描述中任意一個(gè)問(wèn)題的東西稱為單例。

解決方案

所有單例的實(shí)現(xiàn)都包含以下兩個(gè)相同的步驟:

  • 將默認(rèn)構(gòu)造函數(shù)設(shè)為私有, 防止其他對(duì)象使用單例類的 new運(yùn)算符。
  • 新建一個(gè)靜態(tài)構(gòu)建方法作為構(gòu)造函數(shù)。 該函數(shù)會(huì) “偷偷” 調(diào)用私有構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象, 并將其保存在一個(gè)靜態(tài)成員變量中。 此后所有對(duì)于該函數(shù)的調(diào)用都將返回這一緩存對(duì)象。

如果你的代碼能夠訪問(wèn)單例類, 那它就能調(diào)用單例類的靜態(tài)方法。 無(wú)論何時(shí)調(diào)用該方法, 它總是會(huì)返回相同的對(duì)象。

真實(shí)世界類比

政府是單例模式的一個(gè)很好的示例。 一個(gè)國(guó)家只有一個(gè)官方政府。 不管組成政府的每個(gè)人的身份是什么, “某政府” 這一稱謂總是鑒別那些掌權(quán)者的全局訪問(wèn)節(jié)點(diǎn)。

單例模式結(jié)構(gòu)

  • 單例 (Singleton) 類聲明了一個(gè)名為 get­Instance獲取實(shí)例的靜態(tài)方法來(lái)返回其所屬類的一個(gè)相同實(shí)例。

    單例的構(gòu)造函數(shù)必須對(duì)客戶端 (Client) 代碼隱藏。 調(diào)用 獲取實(shí)例方法必須是獲取單例對(duì)象的唯一方式。

偽代碼

在本例中, 數(shù)據(jù)庫(kù)連接類即是一個(gè)單例。 該類不提供公有構(gòu)造函數(shù), 因此獲取該對(duì)象的唯一方式是調(diào)用 獲取實(shí)例方法。 該方法將緩存首次生成的對(duì)象, 并為所有后續(xù)調(diào)用返回該對(duì)象。

// 數(shù)據(jù)庫(kù)類會(huì)對(duì)`getInstance(獲取實(shí)例)`方法進(jìn)行定義以讓客戶端在程序各處
// 都能訪問(wèn)相同的數(shù)據(jù)庫(kù)連接實(shí)例。
class Database is
    // 保存單例實(shí)例的成員變量必須被聲明為靜態(tài)類型。
    private static field instance: Database
    // 單例的構(gòu)造函數(shù)必須永遠(yuǎn)是私有類型,以防止使用`new`運(yùn)算符直接調(diào)用構(gòu)
    // 造方法。
    private constructor Database() is
        // 部分初始化代碼(例如到數(shù)據(jù)庫(kù)服務(wù)器的實(shí)際連接)。
        // ……
    // 用于控制對(duì)單例實(shí)例的訪問(wèn)權(quán)限的靜態(tài)方法。
    public static method getInstance() is
        if (Database.instance == null) then
            acquireThreadLock() and then
                // 確保在該線程等待解鎖時(shí),其他線程沒(méi)有初始化該實(shí)例。
                if (Database.instance == null) then
                    Database.instance = new Database()
        return Database.instance
    // 最后,任何單例都必須定義一些可在其實(shí)例上執(zhí)行的業(yè)務(wù)邏輯。
    public method query(sql) is
        // 比如應(yīng)用的所有數(shù)據(jù)庫(kù)查詢請(qǐng)求都需要通過(guò)該方法進(jìn)行。因此,你可以
        // 在這里添加限流或緩沖邏輯。
        // ……
class Application is
    method main() is
        Database foo = Database.getInstance()
        foo.query("SELECT ……")
        // ……
        Database bar = Database.getInstance()
        bar.query("SELECT ……")
        // 變量 `bar` 和 `foo` 中將包含同一個(gè)對(duì)象。

單例模式適合應(yīng)用場(chǎng)景

如果程序中的某個(gè)類對(duì)于所有客戶端只有一個(gè)可用的實(shí)例, 可以使用單例模式。

單例模式禁止通過(guò)除特殊構(gòu)建方法以外的任何方式來(lái)創(chuàng)建自身類的對(duì)象。 該方法可以創(chuàng)建一個(gè)新對(duì)象, 但如果該對(duì)象已經(jīng)被創(chuàng)建, 則返回已有的對(duì)象。

如果你需要更加嚴(yán)格地控制全局變量, 可以使用單例模式。

單例模式與全局變量不同, 它保證類只存在一個(gè)實(shí)例。 除了單例類自己以外, 無(wú)法通過(guò)任何方式替換緩存的實(shí)例。

請(qǐng)注意, 你可以隨時(shí)調(diào)整限制并設(shè)定生成單例實(shí)例的數(shù)量, 只需修改 獲取實(shí)例方法, 即 getInstance 中的代碼即可實(shí)現(xiàn)。

實(shí)現(xiàn)方式

  • 在類中添加一個(gè)私有靜態(tài)成員變量用于保存單例實(shí)例。
  • 聲明一個(gè)公有靜態(tài)構(gòu)建方法用于獲取單例實(shí)例。
  • 在靜態(tài)方法中實(shí)現(xiàn)"延遲初始化"。 該方法會(huì)在首次被調(diào)用時(shí)創(chuàng)建一個(gè)新對(duì)象, 并將其存儲(chǔ)在靜態(tài)成員變量中。 此后該方法每次被調(diào)用時(shí)都返回該實(shí)例。
  • 將類的構(gòu)造函數(shù)設(shè)為私有。 類的靜態(tài)方法仍能調(diào)用構(gòu)造函數(shù), 但是其他對(duì)象不能調(diào)用。
  • 檢查客戶端代碼, 將對(duì)單例的構(gòu)造函數(shù)的調(diào)用替換為對(duì)其靜態(tài)構(gòu)建方法的調(diào)用。

單例模式優(yōu)缺點(diǎn)

  • 你可以保證一個(gè)類只有一個(gè)實(shí)例。

  • 你獲得了一個(gè)指向該實(shí)例的全局訪問(wèn)節(jié)點(diǎn)。

  • 僅在首次請(qǐng)求單例對(duì)象時(shí)對(duì)其進(jìn)行初始化。

  • 違反了單一職責(zé)原則。 該模式同時(shí)解決了兩個(gè)問(wèn)題。

  • 單例模式可能掩蓋不良設(shè)計(jì), 比如程序各組件之間相互了解過(guò)多等。

  • 該模式在多線程環(huán)境下需要進(jìn)行特殊處理, 避免多個(gè)線程多次創(chuàng)建單例對(duì)象。

  • 單例的客戶端代碼單元測(cè)試可能會(huì)比較困難, 因?yàn)樵S多測(cè)試框架以基于繼承的方式創(chuàng)建模擬對(duì)象。 由于單例類的構(gòu)造函數(shù)是私有的, 而且絕大部分語(yǔ)言無(wú)法重寫(xiě)靜態(tài)方法, 所以你需要想出仔細(xì)考慮模擬單例的方法。 要么干脆不編寫(xiě)測(cè)試代碼, 或者不使用單例模式。

golang代碼示例

Go設(shè)計(jì)模式之單例模式講解和代碼示例_Golang_腳本之家 (jb51.net)

到此這篇關(guān)于Go設(shè)計(jì)模式之單例模式圖文詳解的文章就介紹到這了,更多相關(guān)Go單例模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go使用net/url包來(lái)解析URL提取主機(jī)部分

    go使用net/url包來(lái)解析URL提取主機(jī)部分

    這篇文章主要為大家介紹了go使用net/url包來(lái)解析URL提取主機(jī)部分實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • golang中g(shù)in框架接入jwt使用token驗(yàn)證身份

    golang中g(shù)in框架接入jwt使用token驗(yàn)證身份

    本文主要介紹了golang中g(shù)in框架接入jwt使用token驗(yàn)證身份,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 詳解如何在golang項(xiàng)目開(kāi)發(fā)中創(chuàng)建自己的Module

    詳解如何在golang項(xiàng)目開(kāi)發(fā)中創(chuàng)建自己的Module

    既然我們使用了很多開(kāi)源的 module為我們的日常開(kāi)發(fā)提供了很多的便捷性,那我們?cè)撊绾螌?shí)現(xiàn)自己的 module 來(lái)提供給團(tuán)隊(duì)中使用,接下小編就給大家介紹一下在golang項(xiàng)目開(kāi)發(fā)如何創(chuàng)建自己的Module,需要的朋友可以參考下
    2023-09-09
  • 一文總結(jié)Go語(yǔ)言切片核心知識(shí)點(diǎn)和坑

    一文總結(jié)Go語(yǔ)言切片核心知識(shí)點(diǎn)和坑

    都說(shuō)Go的切片用起來(lái)絲滑得很,Java中的List怎么用,切片就怎么用,作為曾經(jīng)的Java選手,因?yàn)榍衅氖褂貌坏卯?dāng),喜提缺陷若干,本文就給大家總結(jié)一下Go語(yǔ)言切片核心知識(shí)點(diǎn)和坑,需要的朋友可以參考下
    2023-06-06
  • 用Go+Vue.js快速搭建一個(gè)Web應(yīng)用(初級(jí)demo)

    用Go+Vue.js快速搭建一個(gè)Web應(yīng)用(初級(jí)demo)

    這篇文章主要介紹了用Go+Vue.js快速搭建一個(gè)Web應(yīng)用(初級(jí)demo),本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-11-11
  • 教你利用Golang可選參數(shù)實(shí)現(xiàn)可選模式

    教你利用Golang可選參數(shù)實(shí)現(xiàn)可選模式

    本文討論Golang函數(shù)可選參數(shù)及函數(shù)類型,以及如何利用可選函數(shù)類型實(shí)現(xiàn)可選模式。同時(shí)通過(guò)構(gòu)造函數(shù)作為示例,實(shí)現(xiàn)強(qiáng)大帶可選參數(shù)的構(gòu)造函數(shù),讓代碼更直觀、靈活、支持?jǐn)U展
    2023-01-01
  • golang中beego入門(mén)

    golang中beego入門(mén)

    Beego是一個(gè)基于Go語(yǔ)言的開(kāi)源框架,用于構(gòu)建Web應(yīng)用程序和API,本文主要介紹了golang中beego入門(mén),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • go程序執(zhí)行交叉編譯的流程步驟

    go程序執(zhí)行交叉編譯的流程步驟

    go程序可用通過(guò)交叉編譯的方式在一個(gè)平臺(tái)輸出多個(gè)平臺(tái)可運(yùn)行的二進(jìn)制包,本文給大家詳細(xì)介紹了go程序執(zhí)行交叉編譯的流程步驟,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-07-07
  • Go語(yǔ)言中的os.Truncate函數(shù)用法解讀

    Go語(yǔ)言中的os.Truncate函數(shù)用法解讀

    這篇文章主要介紹了Go語(yǔ)言中的os.Truncate函數(shù)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-07-07
  • 一文詳解Golang中的匿名變量

    一文詳解Golang中的匿名變量

    匿名變量是一種特殊類型的變量,可以簡(jiǎn)化代碼并提高可讀性,本文將為大家詳細(xì)介紹一下golang中匿名變量的定義、特性和使用方法,需要的可以參考下
    2023-09-09

最新評(píng)論