Size: 1451
Comment:
|
Size: 9037
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
[[TableOfContents]] |
|
Line 5: | Line 7: |
=== singleton ===(单件) * 意图 |
=== singleton(单件) === ==== 意图 ==== |
Line 8: | Line 13: |
* 实现代码 | ==== 实现代码 ==== |
Line 54: | Line 60: |
==== 另一个实现代码 ==== 从[http://members.chello.nl/f.niessink/ TaskCoach]的代码中摘抄,因此许可证为GPL。 -- QiangningHong {{{ #!python class Singleton(type): """Singleton Metaclass""" def __init__(cls, name, bases, dic): super(Singleton, cls).__init__(name, bases, dic) cls.instance = None def __call__(cls, *args, **kwargs): if cls.instance is None: cls.instance = super(Singleton, cls).__call__(*args, **kwargs) return cls.instance }}} 使用方法: {{{ #!python class MyClass(object): __metaclass__ = Singleton ob1 = MyClass() ob2 = MyClass() assert ob1 is ob2 }}} |
|
Line 57: | Line 97: |
=== Chain of Responsibility(职责链) === ==== 意图 ==== 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。 ==== 说明 ==== 用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request. 也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去。 例如,窗口UI对消息的处理:[[BR]] attachment:CORPattern.gif ==== 代码实现 ==== 模拟UI对消息的处理 {{{ #!python class Event: def __init__( self, name ): self.name = name class Widget: def __init__( self, parent = None ): self.__parent = parent def Handle( self, event ): handler = 'Handle_' + event.name if hasattr( self, handler ): method = getattr( self, handler ) method( event ) elif self.__parent: self.__parent.Handle( event ) elif hasattr( self, 'HandleDefault' ): self.HandleDefault( event ) }}} 使用: 当用一个event被Handle,将调用Handle_"event.name",如果没有此函数就调用parent来处理此event,如果还没有被处理,就试着交给HandleDefault()。 例如: {{{ #!python class MainWindow(Widget): def Handle_close( self, event ): print 'MainWindow: ' + event.name def HandleDefault( self, event ): print 'Default: ' + event.name class Button( Widget ): def Handle_click( self, event ): print 'Button: ' + event.name }}} === Proxy(代理) === ==== 意图 ==== 为其他对象提供一种代理以控制对这个对象的访问。[[BR]] attachment:ProxyPattern.gif ==== 代码 ==== {{{ #!python class Proxy: def __init__( self, subject ): self.__subject = subject def __getattr__( self, name ): return getattr( self.__subject, name ) }}} ==== 例子 ==== {{{ #!python class RGB: def __init__( self, red, green, blue ): self.__red = red self.__green = green self.__blue = blue def Red( self ): return self.__red def Green( self ): return self.__green def Blue( self ): return self.__blue }}} 使用Proxy改变Blue函数: {{{ #!python class NoBlueProxy( Proxy ): def Blue( self ): return 0 }}} 使用: >>> rgb = RGB( 100, 192, 240 ) >>> rgb.Red() 100 >>> proxy = Proxy( rgb ) >>> proxy.Green() 192 >>> noblue = NoBlueProxy( rgb ) >>> noblue.Green() 192 >>> noblue.Blue() 0 }}} 使用: >>> rgb = RGB( 100, 192, 240 ) >>> rgb.Red() 100 >>> proxy = Proxy( rgb ) >>> proxy.Green() 192 >>> noblue = NoBlueProxy( rgb ) >>> noblue.Green() 192 >>> noblue.Blue() 0 === Observer(观察者) === ==== 意图 ==== 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 ==== 代码实现 ==== {{{ #!python class Subject: def __init__(self): self._observers = [] def attach(self, observer): if not observer in self._observers: self._observers.append(observer) def detach(self, observer): try: self._observers.remove(observer) except ValueError: pass def notify(self, modifier=None): for observer in self._observers: if modifier != observer: observer.update(self) }}} ==== 例子,用法 ==== {{{ #!python # Example usage class Data(Subject): def __init__(self, name=''): Subject.__init__(self) self.name = name self.data = 0 def setData(self, data): self.data = data self.notify() def getData(self): return self.data class HexViewer: def update(self, subject): print 'HexViewer: Subject %s has data 0x%x' % (subject.name, subject.getData()) class DecimalViewer: def update(self, subject): print 'DecimalViewer: Subject %s has data %d' % (subject.name, subject.getData()) # Example usage... def main(): data1 = Data('Data 1') data2 = Data('Data 2') view1 = DecimalViewer() view2 = HexViewer() data1.attach(view1) data1.attach(view2) data2.attach(view2) data2.attach(view1) print "Setting Data 1 = 10" data1.setData(10) print "Setting Data 2 = 15" data2.setData(15) print "Setting Data 1 = 3" data1.setData(3) print "Setting Data 2 = 5" data2.setData(5) print "Detach HexViewer from data1 and data2." data1.detach(view2) data2.detach(view2) print "Setting Data 1 = 10" data1.setData(10) print "Setting Data 2 = 15" data2.setData(15) }}} === Template Method(模板方法) === ==== 意图 ==== 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 ==== 实现代码 ==== === Visitor(访问者) === ==== 意图 ==== ==== 实现代码 ==== {{{ #!python class Visitor: def __init__(self): self._methodDic={} def default(self, other): print "What's this:", other def addMethod(self, method): self._methodDic[method.getKey()]=method def __call__(self, other): method=self._methodDic.get(\ other.__class__.__name__,self.default) return method(other) }}} ==== 用法、例子 ==== 在MyVisit的函数__call__中定义对target的具体访问操作。 {{{ #!python class MyVisit: """ Instead of deriving from Visitor the work is done by instances with this interface. """ def __init__(self, otherClass): self._msg='Visit: %s'%otherClass.__name__ self._key=otherClass.__name__ def __call__(self, target): print self._msg, target def getKey(self): return self._key # 被访问者 class E1:pass class E2:pass class E3:pass # 用法 collection=[E1(), E1(), E2(), E3()] visitor=Visitor() visitor.addMethod(MyVisit(E1)) visitor.addMethod(MyVisit(E2)) map(visitor, collection) }}} ########################### 输出: Visit: E1 <__main__.E1 instance at 7ff6d0>[[br]] Visit: E1 <__main__.E1 instance at 7ff730>[[br]] Visit: E2 <__main__.E2 instance at 7ff780>[[br]] What's this: <__main__.E3 instance at 7ff7b0>[[br]] # 简化用法 {{{ #!python visitor = Visitor() visitor.addMethod(MyVisit(E1)) a = E1() visitor(a) }}} ######################### 输出:[br] Visit: E1 <__main__.E1 instance at 0x00A91EE0> |
设计模式
介绍
创建型模式
singleton(单件)
意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
实现代码
1 class Singleton:
2 """ A python singleton """
3
4 class __impl:
5 """ Implementation of the singleton interface """
6
7 def spam(self):
8 """ Test method, return singleton id """
9 return id(self)
10
11 # storage for the instance reference
12 __instance = None
13
14 def __init__(self):
15 """ Create singleton instance """
16 # Check whether we already have an instance
17 if Singleton.__instance is None:
18 # Create and remember instance
19 Singleton.__instance = Singleton.__impl()
20
21 # Store instance reference as the only member in the handle
22 self.__dict__['_Singleton__instance'] = Singleton.__instance
23
24 def __getattr__(self, attr):
25 """ Delegate access to implementation """
26 return getattr(self.__instance, attr)
27
28 def __setattr__(self, attr, value):
29 """ Delegate access to implementation """
30 return setattr(self.__instance, attr, value)
31
32
33 # Test it
34 s1 = Singleton()
35 print id(s1), s1.spam()
36
37 s2 = Singleton()
38 print id(s2), s2.spam()
39
40 # Sample output, the second (inner) id is constant:
41 # 8172684 8176268
42 # 8168588 8176268
另一个实现代码
从[http://members.chello.nl/f.niessink/ TaskCoach]的代码中摘抄,因此许可证为GPL。 -- QiangningHong
1 class Singleton(type):
2 """Singleton Metaclass"""
3
4 def __init__(cls, name, bases, dic):
5 super(Singleton, cls).__init__(name, bases, dic)
6 cls.instance = None
7
8 def __call__(cls, *args, **kwargs):
9 if cls.instance is None:
10 cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
11 return cls.instance
使用方法:
结构型模式
行为模式
Chain of Responsibility(职责链)
意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
说明
用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request. 也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去。 例如,窗口UI对消息的处理:BR attachment:CORPattern.gif
代码实现
模拟UI对消息的处理
1 class Event:
2 def __init__( self, name ):
3 self.name = name
4
5 class Widget:
6 def __init__( self, parent = None ):
7 self.__parent = parent
8 def Handle( self, event ):
9 handler = 'Handle_' + event.name
10 if hasattr( self, handler ):
11 method = getattr( self, handler )
12 method( event )
13 elif self.__parent:
14 self.__parent.Handle( event )
15 elif hasattr( self, 'HandleDefault' ):
16 self.HandleDefault( event )
使用: 当用一个event被Handle,将调用Handle_"event.name",如果没有此函数就调用parent来处理此event,如果还没有被处理,就试着交给HandleDefault()。 例如:
Proxy(代理)
意图
为其他对象提供一种代理以控制对这个对象的访问。BR attachment:ProxyPattern.gif
代码
例子
使用Proxy改变Blue函数:
使用: >>> rgb = RGB( 100, 192, 240 )
>>> rgb.Red()
100
>>> proxy = Proxy( rgb )
>>> proxy.Green()
192
>>> noblue = NoBlueProxy( rgb )
>>> noblue.Green()
192
>>> noblue.Blue()
0
}}} 使用: >>> rgb = RGB( 100, 192, 240 )
>>> rgb.Red()
100
>>> proxy = Proxy( rgb )
>>> proxy.Green()
192
>>> noblue = NoBlueProxy( rgb )
>>> noblue.Green()
192
>>> noblue.Blue()
0
Observer(观察者)
意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
代码实现
1 class Subject:
2 def __init__(self):
3 self._observers = []
4
5 def attach(self, observer):
6 if not observer in self._observers:
7 self._observers.append(observer)
8
9 def detach(self, observer):
10 try:
11 self._observers.remove(observer)
12 except ValueError:
13 pass
14
15 def notify(self, modifier=None):
16 for observer in self._observers:
17 if modifier != observer:
18 observer.update(self)
例子,用法
1 # Example usage
2 class Data(Subject):
3 def __init__(self, name=''):
4 Subject.__init__(self)
5 self.name = name
6 self.data = 0
7
8 def setData(self, data):
9 self.data = data
10 self.notify()
11
12 def getData(self):
13 return self.data
14
15
16 class HexViewer:
17 def update(self, subject):
18 print 'HexViewer: Subject %s has data 0x%x' % (subject.name, subject.getData())
19
20
21 class DecimalViewer:
22 def update(self, subject):
23 print 'DecimalViewer: Subject %s has data %d' % (subject.name, subject.getData())
24
25
26 # Example usage...
27 def main():
28 data1 = Data('Data 1')
29 data2 = Data('Data 2')
30 view1 = DecimalViewer()
31 view2 = HexViewer()
32 data1.attach(view1)
33 data1.attach(view2)
34 data2.attach(view2)
35 data2.attach(view1)
36
37 print "Setting Data 1 = 10"
38 data1.setData(10)
39 print "Setting Data 2 = 15"
40 data2.setData(15)
41 print "Setting Data 1 = 3"
42 data1.setData(3)
43 print "Setting Data 2 = 5"
44 data2.setData(5)
45 print "Detach HexViewer from data1 and data2."
46 data1.detach(view2)
47 data2.detach(view2)
48 print "Setting Data 1 = 10"
49 data1.setData(10)
50 print "Setting Data 2 = 15"
51 data2.setData(15)
Template Method(模板方法)
意图
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
实现代码
Visitor(访问者)
意图
实现代码
1 class Visitor:
2 def __init__(self):
3 self._methodDic={}
4
5 def default(self, other):
6 print "What's this:", other
7
8 def addMethod(self, method):
9 self._methodDic[method.getKey()]=method
10
11 def __call__(self, other):
12 method=self._methodDic.get(\
13 other.__class__.__name__,self.default)
14 return method(other)
用法、例子
在MyVisit的函数call中定义对target的具体访问操作。
1 class MyVisit:
2 """
3 Instead of deriving from Visitor the work is
4 done by instances with this interface.
5 """
6 def __init__(self, otherClass):
7 self._msg='Visit: %s'%otherClass.__name__
8 self._key=otherClass.__name__
9
10 def __call__(self, target):
11 print self._msg, target
12
13 def getKey(self):
14 return self._key
15
16 # 被访问者
17 class E1:pass
18 class E2:pass
19 class E3:pass
20
21 # 用法
22
23 collection=[E1(), E1(), E2(), E3()]
24
25 visitor=Visitor()
26 visitor.addMethod(MyVisit(E1))
27 visitor.addMethod(MyVisit(E2))
28
29 map(visitor, collection)
输出:
Visit: E1 <main.E1 instance at 7ff6d0>br Visit: E1 <main.E1 instance at 7ff730>br Visit: E2 <main.E2 instance at 7ff780>br What's this: <main.E3 instance at 7ff7b0>br
# 简化用法
输出:[br] Visit: E1 <main.E1 instance at 0x00A91EE0>