Java 5.0加入了annotation的特性,算是对Decorator模式有了优雅的支持。现在的JUNIT和Hibernate都有了使用annotation的版本,减轻了代码的编写痛苦。但是在Java的GUI领域里面,还没有使用annotation进行消息处理的例子。我想既然Hibernate可以,那么swing应该也可以,可能是被效率和向下兼容的问题束缚住了。
Python从2.4开始提供了Decorator的支持,其形式和Java大体相当,但本质大相径庭。
具体的Decorator说明limodou大侠已经说得很清楚了
http://www.donews.net/limodou/archive/2004/12/19/207521.aspx
下面是我沿用Java annotation的思维 写的一个使用Decorator模式,进行消息处理例子,代码很不完善,but it works!!!!
msg.py
1 import string, threading
2 from time import sleep, time
3
4
5 def dumpObject(object):
6 print '-'*12
7 print 'Dump',object
8 print '\n'.join([s+' = '+str(getattr(object, s)) for s in dir(object)])
9
10 class MessageSample():
11 def __init__(self,fromObject=None,title='',*args):
12 self.fromObject=fromObject
13 self.title=title
14 self.args=args
15
16 class messageManager():
17
18 object=None
19 @staticmethod
20 def instance():
21 if messageManager.object==None:
22 mutex = threading.Lock()
23 mutex.acquire()
24 if messageManager.object==None:
25 messageManager.object=messageManager()
26 mutex.release()
27 return messageManager.object
28
29 def __init__(self):
30 self.queue=[]
31 self.msgMap={}
32 self.mutex = threading.Lock()
33 self.RunMutex = threading.Lock()
34 self.msgThread=None
35 self.isRun=True
36
37 def push(self,msg):
38 #self.mutex.acquire()
39 self.queue.append(msg)
40 #self.mutex.release()
41
42 def pop(self):
43 #self.mutex.acquire()
44 object = self.queue.pop(0)
45 #self.mutex.release()
46 return object
47
48 def registerMsgHandler(self,fromObject,title,handler):
49 self.mutex.acquire()
50 if self.msgMap.has_key((fromObject,title)):
51 self.msgMap[(fromObject,title)].append(handler)
52 else:
53 self.msgMap[(fromObject,title)]=[handler,]
54 self.mutex.release()
55
56 def removeMsgHandler(self,handler):
57 for k,v in self.msgMap.items():
58 if handler in v:
59 self.mutex.acquire()
60 if handler in v:
61 v.remove(handler)
62 self.mutex.release()
63
64 def processMsg(self,msg):
65 self.mutex.acquire()
66 if (msg.fromObject,msg.title) in self.msgMap:
67 handlers=[handler for handler in self.msgMap[(msg.fromObject,msg.title)] if callable(handler)]
68 #print handlers,msg.args
69 for handler in handlers :
70 handler(*msg.args)
71 self.mutex.release()
72
73 def dumpHandlers(self):
74 for k,v in self.msgMap.items():
75 print k,v
76
77 def run(self):
78
79 self.RunMutex.acquire()
80 self.isRun=True
81 self.RunMutex.release()
82 def threadFunction():
83
84 while self.isRun:
85 try:
86 msg=self.pop()
87 if msg!=None:
88 self.processMsg(msg)
89 except:
90 sleep(0.5)
91
92 self.msgThread=threading.Thread(target=threadFunction)
93 self.msgThread.start()
94
95 def stop(self):
96 if self.msgThread != None:
97 self.RunMutex.acquire()
98 self.isRun=False
99 self.RunMutex.release()
100 def eventHandler(title='',fromObject=None):
101 def wrap(fn):
102 messageManager.instance().registerMsgHandler(fromObject,title,fn)
103 return fn
104 return wrap
105
106 def sendMessage(fromObject,title,*args):
107 msg=MessageSample(fromObject,title,*args)
108 messageManager.instance().push(msg)
1 from msg import *
2 from time import sleep
3 import threading
4
5 @eventHandler('New')
6 def OnNewMsg1(str):
7 print 'Get new message1',str
8
9 @eventHandler('New')
10 def OnNewMsg2(str):
11 print 'Get new message2',str
12
13 @eventHandler('exit')
14 def OnExit():
15
16 messageManager.instance().stop()
17 print 'hello'
18 import sys
19 sys.exit(0)
20
21 class comp():
22 def __init__(self):pass
23 class sample():
24 def __init__(self,str):
25 self.str=str
26 @eventHandler(fromObject=self.str,title='SizeChange')
27 def OnSize(x,y):
28 print 'size',x,y,str
29
30 if __name__=='__main__':
31 #messageManager.instance().dumpHandlers()
32 messageManager.instance().run()
33
34 sendMessage(None,'New','hello')
35 s='I am s'
36 s2='I am s2'
37 S=sample(s)
38 SS=sample(s2)
39 sendMessage(s,'SizeChange',800,600)
40 sendMessage(s2,'SizeChange',800,600)
41 sleep(5)
42 messageManager.instance().removeMsgHandler(OnNewMsg2)
43
44 sendMessage(None,'New','hello')
45
46 messageManager.instance().push(MessageSample(title='exit'))#another way
47
Output:
Get new message1 hello
Get new message2 hello
size 800 600 I am s
size 800 600 I am s2
Get new message1 hello
hello
从代码可以看出 不用写什么消息映射表,也不用在代码中显示的进行监听器的注册,只要在我们写的消息处理函数上添加元数据就行了
posted on 2008-06-20 15:32
zarra 阅读(255)
评论(1) 编辑 收藏