1. 程式人生 > >建立類設計模式(5種)——單例模式

建立類設計模式(5種)——單例模式

建立類設計模式(5種)——單例模式

目錄

建立類設計模式(5種)——單例模式

一、匯流排

二、單例模式

三、單例模式的優點和應用

四、單例模式的缺點


一、匯流排

匯流排是計算機各種功能部件或者裝置之間傳送資料、控制訊號等資訊的公共通訊解決方案之一。現假設有如下場景:某中央處理器(CPU)通過某種協議匯流排與一個訊號燈相連,訊號燈有64種顏色可以設定,中央處理器上執行著三個執行緒,都可以對這個訊號燈進行控制,並且可以獨立設定該訊號燈的顏色。抽象掉協議細節(用打印表示),如何實現執行緒對訊號等的控制邏輯。
加執行緒鎖進行控制,無疑是最先想到的方法,但各個執行緒對鎖的控制,無疑加大了模組之間的耦合。下面,我們就用設計模式中的單例模式,來解決這個問題。
什麼是單例模式?單例模式是指:保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。具體到此例中,匯流排物件,就是一個單例,它僅有一個例項,各個執行緒對匯流排的訪問只有一個全域性訪問點,即惟一的例項。

Python程式碼如下:

#encoding=utf8
import threading
import time
#這裡使用方法__new__來實現單例模式
class Singleton(object):#抽象單例
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance
#匯流排
class Bus(Singleton):
    lock = threading.RLock()
    def sendData(self,data):
        self.lock.acquire()
        time.sleep(3)
        print "Sending Signal Data...",data
        self.lock.release()
#執行緒物件,為更加說明單例的含義,這裡將Bus物件例項化寫在了run裡
class VisitEntity(threading.Thread):
    my_bus=""
    name=""
    def getName(self):
        return self.name
    def setName(self, name):
        self.name=name
    def run(self):
        self.my_bus=Bus()
        self.my_bus.sendData(self.name)

if  __name__=="__main__":
    for i in range(3):
        print "Entity %d begin to run..."%i
        my_entity=VisitEntity()
        my_entity.setName("Entity_"+str(i))
        my_entity.start()

執行結果如下:
Entity 0 begin to run...
Entity 1 begin to run...
Entity 2 begin to run...
Sending Signal Data... Entity_0
Sending Signal Data... Entity_1
Sending Signal Data... Entity_2
在程式執行過程中,三個執行緒同時執行(執行結果的前三行先很快打印出來),而後分別佔用匯流排資源(後三行每隔3秒列印一行)。雖然看上去匯流排Bus被例項化了三次,但實際上在記憶體裡只有一個例項。

二、單例模式

單例模式是所有設計模式中比較簡單的一類,其定義如下:Ensure a class has only one instance, and provide a global point of access to it.(保證某一個類只有一個例項,而且在全域性只有一個訪問點)

Singleton

-static uniqueInstance

-singletonData

+static instance

+singletonOperation

三、單例模式的優點和應用

單例模式的優點

1、由於單例模式要求在全域性內只有一個例項,因而可以節省比較多的記憶體空間;
2、全域性只有一個接入點,可以更好地進行資料同步控制,避免多重佔用;
3、單例可長駐記憶體,減少系統開銷。

單例模式的應用舉例

1、生成全域性惟一的序列號;
2、訪問全域性複用的惟一資源,如磁碟、匯流排等;
3、單個物件佔用的資源過多,如資料庫等;
4、系統全域性統一管理,如Windows下的Task Manager;
5、網站計數器。

四、單例模式的缺點

1、單例模式的擴充套件是比較困難的;
2、賦於了單例以太多的職責,某種程度上違反單一職責原則(六大原則後面會講到);
3、單例模式是併發協作軟體模組中需要最先完成的,因而其不利於測試;
4、單例模式在某種情況下會導致“資源瓶頸”。