-- flyaflya [2005-08-04 09:15:17]

1. 模式名称

1.1. FlyweightPattern

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

1.2. 代码

   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 ...

1.3. 测试例子

   1 import unittest
   2 
   3 class InstrumentTests(unittest.TestCase):
   4     def testInstrument(self):
   5         ibm1 = Instrument("IBM")
   6         ms = Instrument("MS")
   7         ibm2 = Instrument("IBM")
   8         self.assertEquals(id(ibm1), id(ibm2))
   9         self.assertNotEquals(id(ibm1), id(ms))
  10 
  11         self.assertEquals(2, len(Instrument._InstrumentPool),
  12             "Total instruments allocated")
  13 
  14         # This bit assumes CPython memory allocation:
  15         del(ibm1)
  16         del(ibm2)
  17         # 每一次调用Instrument,因其函数__new__中的Instrument._InstrumentPool[name]是weakref,只有obj = object.__new__(cls)引用一次。所以del(ibm1)和del(imb2)后引用计数达到0,对象被清理。
  18         self.assertEquals(1, len(Instrument._InstrumentPool),
  19             "Total instruments allocated")
  20 
  21 
  22 if __name__=='__main__':
  23     unittest.main()

1.4. 特殊说明