1. 程式人生 > >Python的工廠模式和單例模式

Python的工廠模式和單例模式

工廠模式:

解耦 定義類或方法,讓其功能越單一越好

#!/usr/bin/python
#coding:utf-8
class Cake():
    def __init__(self,weidao="預設"):

        self.taste=weidao

class AppleCake(object):
    def __init__(self,weidao="蘋果"):
        self.taste = weidao

class OrangeCake(object):
    def __init__(self,weidao="橘子"):
        self.taste = weidao



class CakeStore(object):
    def taste(self,weidao):
        if weidao == "蘋果":
            cake = AppleCake()
            print("------味道%s------"%cake.taste)
        elif weidao == "橘子":
	    cake = OrangeCake()
            print("---------味道%s------"%cake.taste)
haolilai = CakeStore()
haolilai.taste("橘子")

[
[email protected]
python]# python 工廠方法.py ---------味道橘子------

在這個程式碼中如果我們想再增加一種口味的蛋糕就需要在CakeStore()這個類裡面增加程式碼,在外面再寫一個類,這樣不太好

工廠方法:

class CakeFactory(object):
    def CreateCake(self,weidao):
        if weidao == "蘋果":
            cake = AppleCake()
        elif weidao == "橘子":
            cake = OrangeCake()
        return cake  #這裡一定要有返回值,因為我們需要這個函式的執行結果在另一個函式裡面呼叫

class CakeStore(object):
    def __init__(self):
        self.factory = CakeFactory()
    def taste(self,weidao):
        cake = self.factory.CreateCake(weidao)
        print("-----品嚐味道:%s-----"%cake.taste)
haolilai = CakeStore()
haolilai.taste("橘子")

[
[email protected]
python]# python 工廠方法.py -----品嚐味道:橘子-----

單例模式 __new__方法

class Test(object):
    #初始化功能,往往完成物件屬性的設定
	def __init__(self):
        self.num = 100
        print("-------100------")
        print(self)
    #完成建立一個物件
    #當a = Test()執行的時候,是先呼叫__new__方法完成建立物件,然後緊接著呼叫__init__(),一般不重寫new方法

    def __new__(cls):  
        print("---new--------")
        print(cls)
        return super().__new__(cls) #cls表示當前類,即建立一個當前類的物件。 返回建立的物件,這樣__init__中的self就可以呼叫此物件。
    def __str__(self):
        return "hahah"


a = Test()
print(a.num)
print(a)

#!/usr/bin/python
#coding=utf-8

class Singleton(object):
    __instance = None  #類屬性,可以通過類名去呼叫
    __first_init = False

    def __new__(cls,age,name):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)  #cls相當於類
        return cls.__instance

    def __init__(self,age,name):
        if not self.__first__init:
            self.age = age
            self.name = name
            Singleton.__first__init = True

a = Singleton(18,"haha")
b = Singleton(8,"hahah")

__new__方法總結:

  • 至少有一個引數cls,代表要例項化的類,此引數在例項化時由python直譯器自動提供
  • 必須要有返回值,返回例項化出來的例項,這點在自己實現__new__時需要特別注意,可以return父類__new__出倆的例項,或者是object的__new__出來的例項
  • __init__有一個引數self,就是這個__new__的返回例項,__init__在__new__的基礎上可以完成其它初始化的動作,__init__不需要返回值
  • 我們可以將類比作製造商,__new__就是前期的原始材料的購買環節,__init__就是在原有材料的基礎上加工、初始化商品環節。
#!/usr/bin/python4
#coding:utf-8

class Test(object):
    def __init__(self):
        self.num = 100
        print("---init---")
        print(self)
    def __new__(cls):
        print("---new---")
        print(cls)
        return super().__new__(cls)

#   def __str__(self):
#       return "xxxx"

a = Test()
print(a.num)
print(a)

在這裡插入圖片描述 #!/usr/bin/python #coding=utf-8

class Singleton(object): __instance = None #類屬性,可以通過類名去呼叫 __first_init = False

def __new__(cls,age,name):
    if not cls.__instance:
        cls.__instance = object.__new__(cls)  #cls相當於類
    return cls.__instance

def __init__(self,age,name):
    if not self.__first__init:
        self.age = age
        self.name = name
        Singleton.__first__init = True

a = Singleton(18,"haha")
b = Singleton(8,"hahah")

單例控制:

#!/usr/bin/python 
#coding:utf-8
class singleton(object):
    __instance = None
    def __new__(cls):
        if cls.__instance == None:
            cls.__instance=object.__new__(cls)   #等價於(super).__new__(cls)
        return cls.__instance

a = singleton()
b = singleton()
print(a)
print(b)

在這裡插入圖片描述 在__init__部分完成初始化的控制,只初始化一次。