随笔 - 67  文章 - 79  trackbacks - 0
<2008年6月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿(1)

随笔档案

文章档案

相册

搜索

  •  

最新评论

阅读排行榜

评论排行榜

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 阅读(256) 评论(1)  编辑  收藏

FeedBack:
# re: Python Decorator[未登录] 2008-07-02 13:38 apple
您的代码我总是看的云里雾里的~~~  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: