享元模式-Python实现

享元模式

定义

享元模式是一种用于解决资源和性能压力时会使用到的设计模式,它的核心思想是通过引入数据共享来提升性能。

场景

例如,在开发3D游戏时,有成千上万的士兵或者有成千上万棵树,如果一个3D地带的每个对象都单独创建,不使用数据共享,那么性能是无法接受的。

要创建成千上万棵树,如果他们的数据属性和行为都是一样的,那就黏到一块了。这时就会有:可变数据不可变数据的概念。

创建相同类型的对象时,共享不可变的数据,而每个对象又有其独立的数据--可变的数据(不可共享数据),这部分数据由外部传入。

实现

假设,我们需要创建成千上万棵树,有苹果、梨和樱桃3种树,每种树不同的年龄,且分布在不同的地理位置。

我们将苹果树、梨树、樱桃树当做是不可变数据,可以共享。

将树的年龄,树的坐标位置当做可变数据,不可共享,由外部传入。

import random
from enum import Enum

TreeType = Enum('TreeType', 'apple_tree cherry_tree peach_tree')


class Tree:
    pool = dict()  # pool代表这个类的对象池——可以理解为一个对象数据的缓存。

    def __new__(cls, tree_type):
        obj = cls.pool.get(tree_type, None)
        if not obj:  # 不存在同类型的树,则新建,即通过__new__来限制类的实例化,只允许实例化不同类型的对象。
            obj = object.__new__(cls)
            cls.pool[tree_type] = obj
            obj.tree_type = tree_type
        return obj

    def render(self, age, x, y):
        print('类型-{} 树龄-{} 位置-({},{})'.format(self.tree_type, age, x, y))


def main():
    rnd = random.Random()
    age_min, age_max = 1, 100  # 树龄的区间
    min_point, max_point = 0, 100  # 树的地理位置区间

    # 创建5棵苹果树
    for _ in range(5):
        t1 = Tree(TreeType.apple_tree)
        t1.render(rnd.randint(age_min, age_max),
                  rnd.randint(min_point, max_point),
                  rnd.randint(min_point, max_point)
                  )

    # 创建3棵樱桃树
    for _ in range(3):
        t1 = Tree(TreeType.cherry_tree)
        t1.render(rnd.randint(age_min, age_max),
                  rnd.randint(min_point, max_point),
                  rnd.randint(min_point, max_point)
                  )

    # 创建2棵梨树
    for _ in range(2):
        t1 = Tree(TreeType.peach_tree)
        t1.render(rnd.randint(age_min, age_max),
                  rnd.randint(min_point, max_point),
                  rnd.randint(min_point, max_point)
                  )

    print(Tree.pool)


if __name__ == '__main__':
    main()

享元模式与单例模式

单例模式限制的是一个类只允许有一个实例存在。

而享元模式则是一个类只允许创建不同类型的对象,这样保证同一类型的对象共享不可变数据。

你可能感兴趣的:(设计模式之美,设计模式,python)