python设计模式之享元模式

0 评论
/ /
918 阅读
/
64783 字
26 2018-07

享元模式

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