享元模式
Flyweight模式,顾名思义,就是共享元数据,在python这个动态语言中可以提高程序性能和效率,比如从一个文件读取很多的字符串,而这些字符串必定重复,所以可以使用这个模式将其存在一个pool中
python的例子(我将提出一系列的例子不同方式实现这个功能)
普通青年版,看了Gof,可能就会有这样基础的一段代码:
class Spam(object):
def __init__(self, a, b):
self.a = a
self.b = b
class SpamFactory(object):
def __init__(self):
self.__instances = dict()
def get_instance(self, a, b):
# 在实例化后生成一个字典,当新的元祖对不存在就缓存起来
if (a, b) not in self.__instances:
self.__instances[(a, b)] = Spam(a, b)
return self.__instances[(a, b)]
# 这个和上面的意思完全一样, 这是为了在最后断言下2个工厂缓存的数据是不是能共享
class Egg(object):
def __init__(self, x, y):
self.x = x
self.y = y
class EggFactory(object):
def __init__(self):
self.__instances = dict()
def get_instance(self, x, y):
if (x, y) not in self.__instances:
self.__instances[(x, y)] = Egg(x, y)
return self.__instances[(x, y)]
spamFactory = SpamFactory()
eggFactory = EggFactory()
assert spamFactory.get_instance(1, 2) is spamFactory.get_instance(1, 2)
assert eggFactory.get_instance('a', 'b') is eggFactory.get_instance('a', 'b')
# spamFactory存储的这个元祖和eggFactory存储的不是一个东西
assert spamFactory.get_instance(1, 2) is not eggFactory.get_instance(1, 2)
上面的是最简单能想到的,也是我见过用得最多的一种, 可是还有梦想青年版, 因为上面的东西是可以抽象出来的, 比如上面只能传入a,b2个,再多了就不行了,其他的风格也不行,比如我想缓存键值对,所以想起来了args和*kwargs
class FlyweightFactory(object):
def __init__(self, cls):
self._cls = cls
self._instances = dict()
# 使用*args, **kargs这样的方式抽象实现的cls的参数数量和类型
def get_instance(self, *args, **kargs):
# 如果键在字典中,返回这个键所对应的值。如果键不在字典中,向字典 中插入这个键
return self._instances.setdefault(
(args, tuple(kargs.items())),
self._cls(*args, **kargs))
class Spam(object):
# 我这里实现的是3个参数,这个随意
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
class Egg(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
SpamFactory = FlyweightFactory(Spam)
EggFactory = Flywe