第7篇---Python设计模式之享元模式+含代码实现+学习python的赶快进
享元模式概念:
运用共享技术有效的支持大量细粒度的对象。。简单来说,在我们玩游戏的时候,场景中有一万棵密密麻麻的树,难道我们要把树实例化一万次吗? 你要知道,实例化一万次,内存是要爆炸的,这里我们就可以用享元模式。 实例化一次树,描绘千万棵树的时候只是将坐标改一下。
满足一下条件可以用享元模式:
- ①:应用需要使用大量的对象
- ②:对象太多,存储/渲染它们的代价太大。 存在多组不同的对象可被相对更少的共享数据所替代。
- ③:对象ID对于应用不重要,对象共享会造成ID的破坏。
案例一:
我们这里就实现概念中我刚才举的那个例子。 这里有三种树: apple_tree,cherry_tree,peach_tree。同一种类型,我们这里只能实例化一次。在Tree中的__new__()方法中进行控制,跟单例模式有点像哦。对象创建好,我们把对象放在一个pool字典中,为了在后面验证我们对每棵树真的只实例化了一次。在Tree类中,我们还定义了一个render()方法,可以理解为描绘树的一个函数。
接下来看main方法中, 树的年龄让随机产生,树的坐标也让随机产生。。开始生产树了。首先对apple_tree创了10棵,其实每次实例化的时候都是那个对象,只不过改了坐标和树的年龄,同理创建了cherry_tree树3棵,peach_tree树5棵。 最后我们验证了: 传入不同的树,创建不同的对象,传入相同的树,创建的对象是相同的(同一个)。
import random
from enum import Enum
TreeType = Enum('TreeType', 'apple_tree cherry_tree peach_tree')
class Tree:
pool = dict()
def __new__(cls, tree_type):
obj = cls.pool.get(tree_type, None) # 获取字典中tree_type数据,若没有则返回的是None
if not obj:
obj = object.__new__(cls)
cls.pool[tree_type] = obj
obj.tree_type = tree_type
return obj
def render(self, age, x, y):
print('render a tree of type {} and age {} at {},{}'.format(self.tree_type, age, x, y))
if __name__ == '__main__':
rnd = random.Random()
age_min, age_max = 1, 30
min_point, max_point = 0, 100
tree_counter = 0
# 10棵苹果树
for _ in range(10):
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))
tree_counter += 1
# 3棵樱桃树
for _ in range(3):
t2 = Tree(TreeType.cherry_tree)
t2.render(rnd.randint(age_min, age_max),
rnd.randint(min_point, max_point),
rnd.randint(min_point, max_point))
tree_counter += 1
# 5棵树
for _ in range(5):
t3 = Tree(TreeType.peach_tree)
t3.render(rnd.randint(age_min, age_max),
rnd.randint(min_point, max_point),
rnd.randint(min_point, max_point))
tree_counter += 1
print('trees rendered: {}'.format(tree_counter))
print('tree actually created: {}'.format(len(Tree.pool)))
t4 = Tree(TreeType.cherry_tree)
t5 = Tree(TreeType.cherry_tree)
t6 = Tree(TreeType.apple_tree)
print('{} == {} ? {}'.format(id(t4), id(t5), id(t4) == id(t5)))
print('{} == {} ? {}'.format(id(t5), id(t6), id(t5) == id(t6)))
程序的输出结果: