-- flyaflya [DateTime(2005-08-04T09:15:17Z)] TableOfContents

1. 模式名称

1.1. FlyweightPattern

运用共享技术有效地支持大量细粒度的对象。

1.2. 代码

Toggle line numbers
   1 #实现过程类似于singleton模式
   2 
   3 import weakref
   4 #weekref产生的value不能保持对象存在。当对象不包括weakref在内的引用计数达到0时,对象将被删除。
   5 
   6 class Instrument(object):
   7     _InstrumentPool = weakref.WeakValueDictionary()
   8 
   9     def __new__(cls, name):
  10         '''Instrument(name)
  11         Create a new instrument object, or return an existing one'''
  12         obj = Instrument._InstrumentPool.get(name, None)
  13 
  14         if not obj:
  15             print "new",name
  16             obj = object.__new__(cls)
  17             Instrument._InstrumentPool[name] = obj
  18 
  19         return obj
  20 
  21     def __init__(self, name):
  22         '''Complete object construction'''
  23         self.name = name
  24         print "New instrument @%04x, %s" % (id(self), name)
  25 
  26         # ... connect instrument to datasource ...
  27 === 测试例子 ===
  28 import unittest
  29 
  30 class InstrumentTests(unittest.TestCase):
  31     def testInstrument(self):
  32         ibm1 = Instrument("IBM")
  33         ms = Instrument("MS")
  34         ibm2 = Instrument("IBM")
  35         self.assertEquals(id(ibm1), id(ibm2))
  36         self.assertNotEquals(id(ibm1), id(ms))
  37 
  38         self.assertEquals(2, len(Instrument._InstrumentPool),
  39             "Total instruments allocated")
  40 
  41         # This bit assumes CPython memory allocation:
  42         del(ibm1)
  43         del(ibm2)
  44         # 每一次调用Instrument,因其函数__new__中的Instrument._InstrumentPool[name]是weakref,只有obj = object.__new__(cls)引用一次。所以del(ibm1)和del(imb2)后引用计数达到0,对象被清理。
  45         self.assertEquals(1, len(Instrument._InstrumentPool),
  46             "Total instruments allocated")
  47 
  48 
  49 if __name__=='__main__':
  50     unittest.main()

1.3. 特殊说明