Dirty Flag 模式及其应用
来源:互联网 发布:2017淘宝店怎么刷销量 编辑:程序博客网 时间:2024/06/05 03:05
之前在开发中就发现“dirty”是一种不错的解决方案:可以用来延缓计算或者避免不必要的计算。后来在想,这应该也算一种设计模式吧,于是搜索“Dirty设计模式”,没有什么结果,然后换成英文“Dirty design pattern”,搜到了《game programming patterns》这本电子书。书中介绍了Dirty Flag 模式在游戏客户端的应用场景,如果英文不好,这里也有中文翻译。本文结合几个具体的例子,介绍什么是Dirty Flag 模式,并分析该模式的适用场景以及使用注意事项。
什么是Dirty Flag:
简单来说,就是用一个标志位(flag)来表示一组数据的状态,这些数据要么是用来计算,或者用来需要同步。在满足条件的时候设置标志位,然后需要的时候检查(check)标志位。如果设置了标志位,那么表示这组数据处于dirty状态,这个时候需要重新计算或者同步。如果flag没有被设置,那么可以不计算(或者利用缓存的计算结果)。另外,在两次check之间,即使有多次标志位的设置,也只需要计算一次。
因此,Dirty Flag模式的本质作用在于:延缓计算或数据同步,甚至减少无谓的计算或者同步。计算比较容易理解,对于同步,后面也会给出例子。在后面的描述中,除非特殊说明,计算也包含了同步。
Dirty Flag使用实例:
首先,《game programming pattern》中的例子非常形象生动,图文并茂,建议直接阅读原文,本文不再复述。接下来介绍几个其他的例子。
First
1 def set_need_tick(self, is_need):2 self.need_tick = is_need3 4 def tick(self):5 if self.need_tick:6 self.do_tick() # do_tick 需要做大量的检查,较为耗时
1 def dummy_tick(self):2 pass3 def set_need_tick(self, is_need):4 if is_need:5 self.tick = self.do_tick6 else:7 self.tick = self.dummy_tick
Second
1 class cached_property(object): 2 """ A property that is only computed once per instance and then replaces 3 itself with an ordinary attribute. Deleting the attribute resets the 4 property. """ 5 6 def __init__(self, func): 7 update_wrapper(self, func) 8 self.func = func 9 10 def __get__(self, obj, cls):11 if obj is None: return self12 value = obj.__dict__[self.func.__name__] = self.func(obj)13 return value
1 def set_property_dirty(self, property_name):2 self.__dict__.pop(property_name, None)
在需要的时候调用这个设置函数就行了,在这个例子中,并没有对某个属性的设置和检查,但配合之前的cached_property,作用是很明显的:缓存计算结果,需要的时候重新计算。下面是完整测试代码
1 import functools, time 2 class cached_property(object): 3 """ A property that is only computed once per instance and then replaces 4 itself with an ordinary attribute. Deleting the attribute resets the 5 property. """ 6 7 def __init__(self, func): 8 functools.update_wrapper(self, func) 9 self.func = func10 11 def __get__(self, obj, cls):12 if obj is None: return self13 value = obj.__dict__[self.func.__name__] = self.func(obj)14 return value15 16 class TestClz(object):17 @cached_property18 def complex_calc(self):19 print 'very complex_calc'20 return sum(range(100))21 22 def __set_property_dirty(self, property_name = 'complex_calc'):23 self.__dict__.pop(property_name, None)24 25 def some_action_effect_property(self):26 self.__set_property_dirty()27 28 29 30 if __name__=='__main__':31 t = TestClz()32 print '>>> first call'33 print t.complex_calc34 print '>>> second call'35 print t.complex_calc36 print '>>>third call'37 t.some_action_effect_property()38 print t.complex_calc
Third
Fourth
Fifth
适用场景:
使用条件:
注意事项:
- Dirty Flag 模式及其应用
- Dirty Flag 模式及其应用
- Dirty Flag 模式及其应用
- Dirty Flag 模式及其应用
- Dirty Flag 模式及其应用
- Dirty Flag 模式及其应用
- 装饰者模式及其应用
- Java代理模式及其应用
- 装饰者模式及其应用
- intent FLAG 应用情况
- android Flag启动模式
- 浅谈Flag模式
- Intent Flag启动模式
- Composite模式及其在JSF中的应用
- Composite模式及其在JSF中的应用
- OpenGL中的选择模式及其应用
- 遥感应用模式多样化趋势及其市场前景
- 工厂模式原理及其简单应用
- Java高级程序员面试宝典之网站架构
- 堆内存和栈内存详解
- 工具 | Procexp工具使用及案例说明
- NumPy学习笔记(2)--Array数组和矩阵基本运算
- c++ Oracle OCCI 编程
- Dirty Flag 模式及其应用
- TDDL、Amoeba、Cobar、MyCAT架构比较
- bootstrap Validator 模态框、jsp、表单验证 Ajax提交
- 利用Java字节流的缓冲区:录入文件的路径,将文件拷贝到当前项目下
- 快牙网传——远程相机
- Spring3:AOP
- JQuery-DOM对象和JQuery对象的相互转换
- INV期间关闭后的状态为Closed not Summarized
- 使用multiprocessing时的<DictProxy object, typeid 'dict' at ; '__str__()' failed>