设计模式(python实现)--享元模式(Flyweight)

2020-01-29  本文已影响0人  远行_2a22

Flyweight

动机(Motivation)

模式定义

运行共享技术有效地支持大量细粒度的对象。
——《设计模式》GoF

要点总结

例子

# -*- coding:utf-8 -*-
import random


class TreeType(object):
    Apple = 0
    Cherry = 1
    Peach = 2


class Tree(object):
    tree_pool = {}

    def __new__(cls, tree_type):
        obj = cls.tree_pool.get(tree_type)
        if not obj:
            obj = object.__new__(cls)
            obj.tree_type = tree_type
            cls.tree_pool[tree_type] = obj
        return obj

    def render(self, x, y):
        print('render a tree of type {} at ({}, {})'.format(self.tree_type, x, y))


def main():
    rnd = random.Random()
    min_point, max_point = 0, 100
    tree_counter = 0
    for _ in range(10):
        t1 = Tree(TreeType.Apple)
        t1.render(rnd.randint(min_point, max_point),
                  rnd.randint(min_point, max_point))
        tree_counter += 1

    for _ in range(3):
        t2 = Tree(TreeType.Cherry)
        t2.render(rnd.randint(min_point, max_point),
                  rnd.randint(min_point, max_point))
        tree_counter += 1

    for _ in range(5):
        t3 = Tree(TreeType.Peach)
        t3.render(rnd.randint(min_point, max_point),
                  rnd.randint(min_point, max_point))
        tree_counter += 1

    print('trees rendered: {}'.format(tree_counter))
    print('trees actually created: {}'.format(len(Tree.tree_pool)))
    t4 = Tree(TreeType.Cherry)
    t5 = Tree(TreeType.Cherry)
    print('{} == {}? {}'.format(id(t4), id(t5), id(t4) == id(t5)))
    t6 = Tree(TreeType.Apple)
    print('{} == {}? {}'.format(id(t5), id(t6), id(t5) == id(t6)))


if __name__ == '__main__':
    main()

输出:

render a tree of type 0 at (25, 60)
render a tree of type 0 at (43, 41)
render a tree of type 0 at (67, 78)
render a tree of type 0 at (73, 77)
render a tree of type 0 at (96, 59)
render a tree of type 0 at (98, 16)
render a tree of type 0 at (59, 72)
render a tree of type 0 at (12, 40)
render a tree of type 0 at (10, 60)
render a tree of type 0 at (52, 44)
render a tree of type 1 at (100, 26)
render a tree of type 1 at (37, 12)
render a tree of type 1 at (11, 46)
render a tree of type 2 at (23, 22)
render a tree of type 2 at (74, 32)
render a tree of type 2 at (36, 15)
render a tree of type 2 at (49, 4)
render a tree of type 2 at (33, 27)
trees rendered: 18
trees actually created: 3
4427929552 == 4427929552? True
4427929552 == 4427929488? False

输出结果可知,虽然渲染了18棵树,但仅分配了3棵树的内存。
因为同一类树只分配了一次内存,因此id(t4)==id(t5).
即当使用享元时,我们不能依赖对象的ID来判断。
object.__new__用法可以参考Python中的new(cls) 以及 单例模式

上一篇下一篇

猜你喜欢

热点阅读