FlyweightPattern定义》FlyweightPattern是pool技术的一个重要实现,其定义如下:Usesharingtosupportlargenumbersoffine-grainedobjectsefficiently.(使用共享对象可以有效支持大量细粒度对象。)”摘自:秦晓波。《设计纹样之禅(第2版)(华章原创精品)》。iBooks."当应用程序使用大量对象时,这些对象数量多会造成很大的存储开销,应该考虑。另外,对象的大部分状态都可以是外部状态。如果删除对象的外部状态,可以比较快的使用它。用很少的共享对象来代替很多组对象,这时候可以考虑使用享元模式”摘自:程杰。是存储的,怎么存储的,了解享元模式的应用场景,为了减少内存的使用,提出了object元素的固定部分,以hashmap的形式存储,这个信息不会为创建eachobjectinstance,butallinstancessharedthisdata.参考Java的UML图如下:@startumlFlyweightFactory*-->FlyweightFlyweight<|--ConcreteFlyweightFlyweight<|--UnsharedConcreteFlyweightClient-->FlyweightFactoryClient-->UnsharedConcreteFlyweightClient-->ConcreteFlyweight@enduml代码实现了看似复杂的javaUML模型,其用python实现起来比较简单,就是利用python类的类变量,在类变量中存储共享信息,共享这些数据通过将key值添加到类变量的pool中,并定义从pool中获取数据的接口就可以了。'''一个享元模式的应用例子,假设我们在游戏开发过程中需要创建一个森林,森林中有不同的树种,树种只有几种,固定的,而其他如位置、树龄等则不同。这时可以提出各种树类型共享的部分作为共享类变量'''importrandomfromenumimportEnumTreeType=Enum('TreeType','apple_treecherry_treepeach_tree')classTree:pool=dict()#Define对象池def__new__(cls,tree_type):obj=cls.pool.get(tree_type,None)#从对象池中获取对象,如果None不填则不填ifobj:obj=object.__new__(cls)#新建一个对象cls.pool[tree_type]=obj#存入对象池obj.tree_type=tree_typereturnobjdefrender(self,age,x,y):'''一直没搞懂render中的作用flyweightmode是什么,其实render函数代表的是一个操作。例如:连接数据库,pool代表与数据库的连接池,render代表get、commit等各种数据库交互动作,此时age、x、y代表每个动作的内容'''print('renderatreeoftype{}andage{}at({},{})'.format(self.tree_type,age,x,y))defmain():rnd=random.Random()age_min,age_max=1,30#单位是年份min_point,max_point=0,100tree_counter=0for_inrange(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+=1for_inrange(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+=1for_inrange(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+=1print('呈现的树:{}'.format(tree_counter))print('实际创建的树:{}'.format(len(Tree.pool)))t4=Tree(TreeType.cherry_tree)t4.render(rnd.randint(age_min,age_max),rnd.randint(min_point,max_point),rnd.randint(min_point,max_point))t5=Tree(TreeType.cherry_tree)t5.render(rnd.randint(age_min,age_max),rnd.randint(min_point,max_point),rnd.randint(min_point,max_point))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)))if__name__=="__main__":main()知识点下集预告代理模式
