<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 確保對象的唯一性——單例模式 (一) 3.1 單例模式的動機 對于一個軟件系統的某些類而言,我們無須創建多個實例。舉個大家都熟知的例子——Windows任務管理器,如圖3-1所示,我們可以做一個這樣的嘗試,在Windows的“任務欄”的右鍵彈出菜單上多次點擊“啟動任務管理器”,看能否打開多個任務管理器窗口?如果你的桌面出現多個任務管理器,我請你吃飯,微笑(注:電腦中毒或私自修改Windows內核者除外)。通常情況下,無論我們啟動任務管理多少次,Windows系統始終只能彈出一個任務管理器窗口,也就是說在一個Windows系統中,任務管理器存在唯一性。為什么要這樣設計呢?我們可以從以下兩個方面來分析:其一,如果能彈出多個窗口,且這些窗口的內容完全一致,全部是重復對象,這勢必會浪費系統資源,任務管理器需要獲取系統運行時的諸多信息,這些信息的獲取需要消耗一定的系統資源,包括CPU資源及內存資源等,浪費是可恥的,而且根本沒有必要顯示多個內容完全相同的窗口;其二,如果彈出的多個窗口內容不一致,問題就更加嚴重了,這意味著在某一瞬間系統資源使用情況和進程、服務等信息存在多個狀態,例如任務管理器窗口A顯示“CPU使用率”為10%,窗口B顯示“CPU使用率”為15%,到底哪個才是真實的呢?這純屬“調戲”用戶,偷笑,給用戶帶來誤解,更不可取。由此可見,確保Windows任務管理器在系統中有且僅有一個非常重要。 ![](http://my.csdn.net/uploads/201204/02/1333304799_4385.gif) 圖3-1 Windows任務管理器 回到實際開發中,我們也經常遇到類似的情況,為了節約系統資源,有時需要確保系統中某個類只有唯一一個實例,當這個唯一實例創建成功之后,我們無法再創建一個同類型的其他對象,所有的操作都只能基于這個唯一實例。為了確保對象的唯一性,我們可以通過單例模式來實現,這就是單例模式的動機所在。 3.2 單例模式概述 下面我們來模擬實現Windows任務管理器,假設任務管理器的類名為TaskManager,在TaskManager類中包含了大量的成員方法,例如構造函數TaskManager(),顯示進程的方法displayProcesses(),顯示服務的方法displayServices()等,該類的示意代碼如下: ``` class TaskManager { public TaskManager() {……} //初始化窗口 public void displayProcesses() {……} //顯示進程 public void displayServices() {……} //顯示服務 …… } ``` 為了實現Windows任務管理器的唯一性,我們通過如下三步來對該類進行重構: (1) 由于每次使用new關鍵字來實例化TaskManager類時都將產生一個新對象,為了確保TaskManager實例的唯一性,我們需要禁止類的外部直接使用new來創建對象,因此需要將TaskManager的構造函數的可見性改為private,如下代碼所示: ``` private TaskManager() {……} ``` (2) 將構造函數改為private修飾后該如何創建對象呢?不要著急,雖然類的外部無法再使用new來創建對象,但是在TaskManager的內部還是可以創建的,可見性只對類外有效。因此,我們可以在TaskManager中創建并保存這個唯一實例。為了讓外界可以訪問這個唯一實例,需要在TaskManager中定義一個靜態的TaskManager類型的私有成員變量,如下代碼所示: ``` private static TaskManager tm = null; ``` (3) 為了保證成員變量的封裝性,我們將TaskManager類型的tm對象的可見性設置為private,但外界該如何使用該成員變量并何時實例化該成員變量呢?答案是增加一個公有的靜態方法,如下代碼所示: ``` public static TaskManager getInstance() { if (tm == null) { tm = new TaskManager(); } return tm; } ``` 在getInstance()方法中首先判斷tm對象是否存在,如果不存在(即tm == null),則使用new關鍵字創建一個新的TaskManager類型的tm對象,再返回新創建的tm對象;否則直接返回已有的tm對象。 需要注意的是getInstance()方法的修飾符,首先它應該是一個public方法,以便供外界其他對象使用,其次它使用了static關鍵字,即它是一個靜態方法,在類外可以直接通過類名來訪問,而無須創建TaskManager對象,事實上在類外也無法創建TaskManager對象,因為構造函數是私有的。 思考 為什么要將成員變量tm定義為靜態變量? 通過以上三個步驟,我們完成了一個最簡單的單例類的設計,其完整代碼如下: ``` class TaskManager { private static TaskManager tm = null; private TaskManager() {……} //初始化窗口 public void displayProcesses() {……} //顯示進程 public void displayServices() {……} //顯示服務 public static TaskManager getInstance() { if (tm == null) { tm = new TaskManager(); } return tm; } …… } ``` 在類外我們無法直接創建新的TaskManager對象,但可以通過代碼TaskManager.getInstance()來訪問實例對象,第一次調用getInstance()方法時將創建唯一實例,再次調用時將返回第一次創建的實例,從而確保實例對象的唯一性。 上述代碼也是單例模式的一種最典型實現方式,有了以上基礎,理解單例模式的定義和結構就非常容易了。單例模式定義如下: 單例模式(Singleton Pattern):確保某一個類只有一個實例,而且自行實例化并向整個系統提供這個實例,這個類稱為單例類,它提供全局訪問的方法。單例模式是一種對象創建型模式。 單例模式有三個要點:一是某個類只能有一個實例;二是它必須自行創建這個實例;三是它必須自行向整個系統提供這個實例。 單例模式是結構最簡單的設計模式一,在它的核心結構中只包含一個被稱為單例類的特殊類。單例模式結構如圖3-2所示: ![](http://my.csdn.net/uploads/201204/02/1333305124_9327.gif) 單例模式結構圖中只包含一個單例角色: ● Singleton(單例):在單例類的內部實現只生成一個實例,同時它提供一個靜態的getInstance()工廠方法,讓客戶可以訪問它的唯一實例;為了防止在外部對其實例化,將其構造函數設計為私有;在單例類內部定義了一個Singleton類型的靜態對象,作為外部共享的唯一實例。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看