1. 程式人生 > >python設計模式(一)之單例模式

python設計模式(一)之單例模式

object ros 通信 提高 單例類 並且 擴展 創建型 以及

  初聞設計模式這個詞匯,對於我來說其實是一頭霧水的,看了一些相關書籍還是覺得有些雲裏霧裏的,於是就想寫幾篇關於基本設計模式的博客,我會從 1.類別,2.定義,3.應用場景,4.代碼實現,5.優缺點,這五個方面給自己理清一下思路,如有不對之處,還望多多指正。

  設計模式類別分為三大類:

    一、創建型:提供實例化的方法,為適合的狀況提供相應的對象創建方法。

    二、結構型:通常用來處理實體之間的關系,使得這些實體能夠更好地協同工作。

    三、行為型:用於在不同的實體進行通信,為實體間的通信提供更容易,更靈活的通信方法。

  首先先來看一下單例模式。

  定義:保證一個類只有一個實例,並提供一個訪問它的全局訪問點。

  類別:單例模式是實例化方法,是一種創建型的設計模式。

  應用場景:有些對象我們只需要一個,如線程池,緩存,網站計數器,如果實例化很多這樣的對象,無疑浪費了很多系統資源,也會使緩存沒有了意義。這時,我們需要一個特殊的類,每次實例化這個類都只有一個這樣的實例,單例模式就為我們提供了這樣的方法。

  代碼實現:

    實現方式1:通過模塊導入的方式。

# singleton.py 

class Singleton1(object):
    def __init__(self,name):
        self.name = name

sing = Singleton1(
jack)
# test.py

from sing.singleton import sing
a = sing
b = sing
a.name = rose
b.name = mike
print(id(a),id(b))  # ==> 4421234192 4421234192
print(a.name)    #==> mike

  我們可以通過打印結果看到實例化出來的兩個對象實際上是同一個對象。

    實現方式2:使用裝飾器

def Singleton(cls):
    _instance = {}

    
def _singleton(*args, **kargs): if cls not in _instance: _instance[cls] = cls(*args, **kargs) return _instance[cls] return _singleton @Singleton class A(object): def __init__(self, x=0): self.x = x a1 = A(2) a2 = A(3)

裝飾器都是閉包函數,每次實例化都會先檢查這個類名是否在_instance字典中出現,如果沒有出現,會將這個類加入到這個字典並且返回,如果出現過了,則會返回之前的實例化的類,參數也是第一次傳入的參數,讓我們看一下打印結果:

print(id(a1),id(a2))  # ==》4430388304 4430388304
print(a1.x,a2.x)    # ==》 2  2

    實現方式3:通過類創建

class Singleton(object):
    __instance = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = super(
                Singleton, cls).__new__(cls)
        return cls.__instance

    def __init__(self, status_number):
        self.status_number = status_number

  這裏要註意self.__new__是優先於self.__init__方法的,每次實例化對象都會先執行__new__,返回了一個類的實例,再進行__init__初始化的。從這個new方法可以看出他返回的都是同一個類屬性。

single1 = Single(jack)
single2 = Single(mike)
print(single1.name)    # ==> mike
print(id(single1),id(single2))  # ==> 4485909640 4485909640

  優點:

   一、節約了系統資源。由於系統中只存在一個實例對象,對與一些需要頻繁創建和銷毀對象的系統而言,單例模式無疑節約了系統資源和提高了系統的性能。

   二、因為單例類封裝了它的唯一實例,所以它可以嚴格控制客戶怎樣以及何時訪問它。

  缺點:

   一、由於單例模式中沒有抽象層,因此單例類的擴展有很大的困難。

   二、單例類的職責過重,在一定程度上違背了“單一職責原則”。

python設計模式(一)之單例模式