【编程思想】【设计模式】【结构模式Structural】享元模式flyweight

Python版

https://github.com/faif/python-patterns/blob/master/structural/flyweight.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
*References:
http://codesnipers.com/?q=python-flyweights

*TL;DR80
Minimizes memory usage by sharing data with other similar objects.
"""

import weakref

class FlyweightMeta(type):

    def __new__(mcs, name, parents, dct):
        """
        Set up object pool

        :param name: class name
        :param parents: class parents
        :param dct: dict: includes class attributes, class methods,
        static methods, etc
        :return: new class
        """
        dct[‘pool‘] = weakref.WeakValueDictionary()
        return super(FlyweightMeta, mcs).__new__(mcs, name, parents, dct)

    @staticmethod
    def _serialize_params(cls, *args, **kwargs):
        """
        Serialize input parameters to a key.
        Simple implementation is just to serialize it as a string
        """
        args_list = list(map(str, args))
        args_list.extend([str(kwargs), cls.__name__])
        key = ‘‘.join(args_list)
        return key

    def __call__(cls, *args, **kwargs):
        key = FlyweightMeta._serialize_params(cls, *args, **kwargs)
        pool = getattr(cls, ‘pool‘, {})

        instance = pool.get(key)
        if instance is None:
            instance = super(FlyweightMeta, cls).__call__(*args, **kwargs)
            pool[key] = instance
        return instance

class Card(object):

    """The object pool. Has builtin reference counting"""
    _CardPool = weakref.WeakValueDictionary()

    """Flyweight implementation. If the object exists in the
    pool just return it (instead of creating a new one)"""
    def __new__(cls, value, suit):
        obj = Card._CardPool.get(value + suit)
        if not obj:
            obj = object.__new__(cls)
            Card._CardPool[value + suit] = obj
            obj.value, obj.suit = value, suit
        return obj

    # def __init__(self, value, suit):
    #     self.value, self.suit = value, suit

    def __repr__(self):
        return "<Card: %s%s>" % (self.value, self.suit)

def with_metaclass(meta, *bases):
    """ Provide python cross-version metaclass compatibility. """
    return meta("NewBase", bases, {})

class Card2(with_metaclass(FlyweightMeta)):

    def __init__(self, *args, **kwargs):
        # print(‘Init {}: {}‘.format(self.__class__, (args, kwargs)))
        pass

if __name__ == ‘__main__‘:
    # comment __new__ and uncomment __init__ to see the difference
    c1 = Card(‘9‘, ‘h‘)
    c2 = Card(‘9‘, ‘h‘)
    print(c1, c2)
    print(c1 == c2, c1 is c2)
    print(id(c1), id(c2))

    c1.temp = None
    c3 = Card(‘9‘, ‘h‘)
    print(hasattr(c3, ‘temp‘))
    c1 = c2 = c3 = None
    c3 = Card(‘9‘, ‘h‘)
    print(hasattr(c3, ‘temp‘))

    # Tests with metaclass
    instances_pool = getattr(Card2, ‘pool‘)
    cm1 = Card2(‘10‘, ‘h‘, a=1)
    cm2 = Card2(‘10‘, ‘h‘, a=1)
    cm3 = Card2(‘10‘, ‘h‘, a=2)

    assert (cm1 == cm2) != cm3
    assert (cm1 is cm2) is not cm3
    assert len(instances_pool) == 2

    del cm1
    assert len(instances_pool) == 2

    del cm2
    assert len(instances_pool) == 1

    del cm3
    assert len(instances_pool) == 0

### OUTPUT ###
# (<Card: 9h>, <Card: 9h>)
# (True, True)
# (31903856, 31903856)
# True
# False

Python转载版

原文地址:https://www.cnblogs.com/demonzk/p/9035437.html

时间: 2024-10-12 20:17:24

【编程思想】【设计模式】【结构模式Structural】享元模式flyweight的相关文章

设计模式(结构型)之享元模式(Flyweight Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(结构型)之外观模式(Facade Pattern)>http://blog.csdn.net/yanbober/article/details/45476527 概述 当一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题.所以需要采用一

设计模式(十)享元模式Flyweight(结构型)

说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面向对象技术可以很好地解决系统一些灵活性或可扩展性或抽象性的问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题.比如:例子1:图形应用中的图元等对象.字处理应用中的字符对象等. 2.解决方案: 享元模式(Flyweight):对象结构型模式运用

设计模式学习08:享元模式

设计模式学习08:享元模式 参考资料 https://www.jianshu.com/p/a2aa75939766 https://www.cnblogs.com/adamjwh/p/9070107.html 简介 Use sharing to support large numbers of fine-grained objects efficiently. 使用共享对象可有效地支持大量的细粒度的对象. 享元模式(Flyweight)又称为 轻量级模式,它是一种对象结构型模式. 面向对象技术可

设计模式(11)享元模式

模式介绍 享元模式用于创建许多小的.相关的对象,而无需为此调用大量开销工作,从而提高性能和可维护性. 享元模式允许对象的许多实例共享它们的内在状态,从而减少与创建它们相关的成本. 示例 我们以Slider(一种类似汉堡的食物)为例. 抽象的享元类 /// <summary> /// The Flyweight class /// </summary> abstract class Slider { protected string Name; protected string Ch

15结构型模式之享元模式

概念 Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用. 角色和职责 抽象享元角色: 所有具体享元类的父类,规定一些需要实现的公共接口. 具体享元角色: 抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法. 享元工厂角色: 负责创建和管理享元角色. 使用场景: 是以共享的方式,高效的支持大量的细粒度的对象. 案例 //相同的信息,但不是同一个人. #include <iostream> using namespace std; #inclu

用最简单的例子说明设计模式(三)之责任链、建造者、适配器、代理模式、享元模式

责任链模式 一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止 使用场景 1)有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定 2)在不明确指定接收者的情况下,向多个对象中的一个提交一个请求 3)可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求 public class Chain { public abstract class Handler { private

设计模式---对象性能模式之享元模式(Flyweight)

一:概念 通过与其他类似对象共享数据来减少内存占用 如果一个应用程序使用了太多的对象, 就会造成很大的存储开销. 特别是对于大量轻量级 (细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为每个字母创建一个对象的话,系统可能会因为大量的对象而造成存储开销的浪费.例如一个字母“a”在文档中出现了100000 次,而实际上我们可以让这一万个字母“a”共享一个对象,当然因为在不同的位置可能字母“a”有不同的显示效果(例如字体和大小等设置不同) ,在这种情况我们可以为将对象的状态分为“外部状态”和“

设计模式课程 设计模式精讲 13-1 享元模式讲解

1 课程讲解 1.1 类型: 1.2 定义: 1.3 应用场景: 1.4 优点: 1.5 缺点: 1.6 扩展: 1.7 和其他设计模式比较: 1 课程讲解 1.1 类型: 结构型: 1.2 定义: ◆定义:提供了减少对象数量从而改善应用所需的对象结构的方式◆运用共享技术有效地支持大量细粒度的对象 (可能对于内存溢出类型的问题解决有效)(池子) 1.3 应用场景: ◆ a 常常应用于系统底层的开发,以便解决系统的性能问题. (系统中如果有大量的对象,可能会造成内存溢出,我们可以把共同的部分抽象出

JavaScript设计模式与开发实践 享元模式

享元(flyweight)模式是一种用于性能优化的模式,"fly"在这里是苍蝇的意思,意为蝇量级.享元模式的核心是运用共享技术来有效支持大量细粒度的对象. 如果系统中因为创建了大量类似的对象而导致内存占用过高,享元模式就非常有用了.在JavaScript 中,浏览器特别是移动端的浏览器分配的内存并不算多,如何节省内存就成了一件非常有意义的事情. 一.内部状态与外部状态 享元模式要求将对象的属性划分为内部状态与外部状态(状态在这里通常指属性).享元模式的目标是尽量减少共享对象的数量,关于

设计模式(十)享元模式(Flyweight)-结构型

享元模式Flyweight 组合模式解决了对象时树形结构时的处理方式.当系统需要大量使用重复的对象,而这些对象要消耗很大的资源时就需要使用享元模式来解决. 单例模式,一个类只有一个唯一的对象.也就是说,不管new多少次,只需要创建这个类的一个对象,如果不采用单例模式,没new一次就会创建一个对象,这对于系统需要使用大量重复的对象,而这些对象需要消耗很大的资源时,是很不划算的,这时就需要使用享元模式. 数据库连接池就是享元模式的典型应用. 享元模式实现原理 享元模式的实现原理图 享元模式的优缺点