在考量系统内存合理使用时,通过享元模式可降低性能压力以及降低资源占用;主要实现是通过共享数据这一思想实现资源的合理分配。
在开发项目时,很多情况下会存在过多的相似对象,该对象有相同的共同点,该共同点在程序设计时,可归为共享数据,不同点可以通过其它方式进行传递赋值。
例如做一个瓶子,盘子外观都是相同的,只有内部数据不同,这个时候假设通过常规方式新建不同的对象,该对象的资源分配是不合理的。
假设产品有矿泉水,只有外包装颜色不同,这时就可以使用享元模式。 实现如下,首先新建一个矿泉水类:
代码语言:javascript复制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_。
经过以上类的编写后,实例化对象,并且查看池中存储了多少个对象:
代码语言:javascript复制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。 完整代码如下:
代码语言:javascript复制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))