在考量系統內存合理使用時,通過享元模式可降低性能壓力以及降低資源佔用;主要實現是通過共享數據這一思想實現資源的合理分配。
在開發項目時,很多情況下會存在過多的相似對象,該對象有相同的共同點,該共同點在程序設計時,可歸爲共享數據,不同點可以通過其它方式進行傳遞賦值。
例如做一個瓶子,盤子外觀都是相同的,只有內部數據不同,這個時候假設通過常規方式新建不同的對象,該對象的資源分配是不合理的。
假設產品有礦泉水,只有外包裝顏色不同,這時就可以使用享元模式。
實現如下,首先新建一個礦泉水類:
class BottledWater(object):
objpool = dict()#記錄生成對象
def show(self, color):#顯示一下顏色
print(self.name,'顏色',color)
def __new__(cls, type):# 使用new 初始化在實例化之前
obj_ = cls.objpool.get(type, None)#沒有找到對象就實例化
if obj_ == None:
obj_ = object.__new__(cls)
cls.objpool[type] = obj_
obj_.name = type
return obj_
objpool = dict()
:礦泉水類中,定義了一個objpool 作爲一個記錄對象的池(字典)
def show(self, color)
:輸出當前對象名以及可變屬性顏色
def __new__(cls, type)
:使用new方法在實例化之前創建對象
obj_ = cls.objpool.get(type, None)
:在對象池中找到當前類型的對象,沒找到則爲None
if obj_ == None:
:對象找不到則開始初始化對象,並且把當前類型對象存入到記錄池中
obj_.name = type
:把type賦值給當前name屬性,以便之後進行輸出顯示
最後返回對象 obj_。
經過以上類的編寫後,實例化對象,並且查看池中存儲了多少個對象:
t1 = BottledWater("礦泉水")
t1.show('紅色')
t2 = BottledWater("礦泉水")
t2.show('藍色')
t3 = BottledWater("礦泉水")
t3.show('綠色')
print('\n')
t1_ = BottledWater("冰紅茶")
t1_.show('紅色')
t2_ = BottledWater("冰紅茶")
t2_.show('藍色')
t3_ = BottledWater("冰紅茶")
t3_.show('綠色')
print('對象一共有:',len(BottledWater.objpool))
在未使用享元模式前,以上新建對象的方法應該會新建出6個對象,但是輸出顯示爲2個:
因爲類型一個爲礦泉水另外一個爲冰紅茶,兩者之間是兩個種類;礦泉水新建對象後是共享數據,不同顏色是可變數據,冰紅茶與礦泉水是兩種不同類型,最後使用len計算池 objpool 長度,判斷類的多少,對象總數爲2。
完整代碼如下:
class BottledWater(object):
objpool = dict()#記錄生成對象
def show(self, color):#顯示一下顏色
print(self.name,'顏色',color)
def __new__(cls, type):# 使用new 初始化在實例化之前
obj_ = cls.objpool.get(type, None)#沒有找到對象就實例化
if obj_ == None:
obj_ = object.__new__(cls)
cls.objpool[type] = obj_
obj_.name = type
return obj_
t1 = BottledWater("礦泉水")
t1.show('紅色')
t2 = BottledWater("礦泉水")
t2.show('藍色')
t3 = BottledWater("礦泉水")
t3.show('綠色')
print('\n')
t1_ = BottledWater("冰紅茶")
t1_.show('紅色')
t2_ = BottledWater("冰紅茶")
t2_.show('藍色')
t3_ = BottledWater("冰紅茶")
t3_.show('綠色')
print('對象一共有:',len(BottledWater.objpool))