SEE:Zope平台综论
Zope 组件架构
ZCA~Zope Component Architecture 跨越思想的应用建筑基础
介绍
潘俊勇 <[email protected]> reply-to [email protected] to python-cn`CPyUG`华蟒用户组 <[email protected]> date Wed, Aug 27, 2008 at 09:24
subject [CPyUG:63538] Python的组件架构扩展
微软有COM组件架构,使用接口来拼装应用,很牛。 对于复杂应用,组件架构大大简化了开发过程,系统更可扩展,柔性更强。
Python上是否有类似的成熟体系?
有的,twisted在用,zope在用,还有很多知名的python软件都在用....
那就是著名的Zope Component Architecture,来自于Zope社区的一个系统,却已经在整个python社区开花结果 了。。。。
发展了若干年的宝物在这里:
http://www.muthukadan.net/docs/zca.html
(绝对不是新鲜玩意了,如果您还不知道,责任不在您,只怪zope社区广告没做好)
即便你做非web的程序,这个也是试用你的,上的例子就是基于pyGTK的。
很简单的概念(适配器、工具),却容下了各种设计模式的纷繁内容,秉承了python"大道至简"的理念。
如果你只想作python脚本级别的开发,这个您可能不那么需要ZCA;
如果您是真正的pythoner开发人员,ZCA绝对是不得不学的附加,我超强力推荐!
广告到此结束。
(如果有人想翻译上面的文章,和俺联系)
白话组件应用开发
举一个例子:
比如你设计了一个登录认证系统,输入用户名、口令,登录。
ok,很简单,搞定了。
过2天,你们老板说,让有gmail帐号的人,也能够登录。。。
能力超强的你,研究了gmail协议,happy hacking,完成了。
过了2天,你老板说windows活动目录上的人,也能够登录。。。
ok,算你狠,苦苦研究ldap协议,有搞定了,我也牛。。。
然后,时代变迁,大家开始用openid登录了
上帝啊,难道我又要...
那么组件架构可以解决这个问题,让你根据接口每次写一个插件就行了,每个插件而且可以重用。你可以去网上下载很多插件即可...
使用ZCA 的期望
关于接口,的确python是已经在用的,只是没有明晰化。
但是一旦使用ZCA,会自带一个内存注册表,可以记录:
- 那些组件实现了那些接口 - 接口之间该如何转换
有了这个注册表,你可以实现:
- 得到一个实现数据量连接对象IDBConnection的对象,程序中可完全不考虑这个是采用mysql还是sqlite - 接口转换,就如同类型转换一样傻瓜:
- 我们知道 str(33) 转换成了 '33' 那么,接口也有类似的功效,比如 IInterfaceB(obj) 可以自动将obj适配出一个新的InterfaceB,适配是扩增对象功能的
基本方法。
上面2点,也就是ZCA的核心:工具Utility和适配Utility,当然还有事件机制,这些都非常有用的。接口是实现这些的基础。
(说这些,是希望招人的时候,能有知道ZCA的人士出现啊。。。)
体验
Chen Houwu
Chen Houwu <[email protected]> reply-to [email protected] to python-cn`CPyUG`华蟒用户组 <[email protected]> date Wed, Aug 27, 2008 at 12:40 subject [CPyUG:63578] Re: Python的组件架构扩展
我补充一下:
- zca中的interface对接口的定义不是强制性的,而是描述性的。
- interface不仅具有明确定义的功能,更重要的是,它是其他技术的基础:
- zca提供了依赖注射和aop能力
- zca提供了规约式编程能力:前件、后件、不变式什么的
- zca提供了事件发布机制
- zca提供了常用设计模式
- 。。。。。很多,一时想不起来了
- zca的一个主导原则是:不要subclass,要delegate,并根据zope2的经验认为前者是造成模块重用的巨大障碍,所以整个zca
都是建立在adapter模式上的。虽然有人认为在这方面,做得太绝对化,有时候带来了不必要的麻烦,但是确实在这个框架下开发组件做到了"高内聚低耦合"。
- 拿zca和com比是不恰当的。com做到了语言无关,zca只是个开发框架。
学习了zca之后,再用spring.net, castle windsor之流,都是那么的看不上眼。在.net/java世界里,需要多个框架一 起解决的问题,一个zca就可以搞定,而且浑然一体、干净清爽。
觉得zca不够pythonic的人,真的应该考虑一下他每项技术要解决的问题是什么,你是否还有比它更干净的解决办法。
Limodou
limodou <[email protected]> reply-to [email protected] to [email protected] date Wed, Aug 27, 2008 at 15:29 subject [CPyUG:63618] Re: Python的组件架构扩展
>> 这些东西都很抽象,有没有用zca解决的非zope开发的实例?
> 有的啊,那篇文章上,就自带的一个例子,做的是一个本地的桌面应用程序,和limodou你的估计有很多相近之处的,你看看肯定会有启发
我把例子简单地看了一下,体会如下:
文章上举的例子(desk)是通过ZCA来处理不同的数据源,如zodb和sqlite3,因此它通过zca作了一个封装。在程序启动时根据命令行(check_use_relational_db())不同来调用不同的初始化处理
if use_rdb: initialize_rdb() else: initialize_odb()
不同的初始化将进行相应的组件的注册。然后在程序中通过象getUtility(IRelationalDatabase)之类的调用得到当时注册的对象进行处理。
而zca提供的重要的功能:
- interface等类定义
- 注册机制
- 获取机制
- 配置机制
因此只有当你程序有些组件需要考虑作成可替换,并且可配置时,使用zca是一个选择。
- 因此我个人的理解
- zca的注册,获取,配置的功能远大于interface。interface改为class也差不多,只不过interface可能有象java一样的检查功能,这一点可能要优于简单的class。但对于小项目是否这么做就不一定了。我之所以不喜欢java主要的一点就是规矩太多,而interface这个东西让我看到了java再现。可能对于大型的团队开发的意义要大于为了爱好而编程的小团体。
- ulipad的mixin机制与zca还是不同。使用zca,你是在程序只对其进行使用,并不是对当前的类进行扩展。而ulipad的mixin是可以对某个类的属性,方法进行扩展。而ulipad中的plugin工作方式与zca差不多。整个ulipad也有类似zca的注册,获取,配置的机制。不过我还不清楚zca中的plugin机制(类似这个的机制)是如果工作的,比如在ulipad中,你在某个类中定义了一个plugin调用,然后根据调用的不同api对plugin的处理有所区别:
- callplugin表示按顺序调用,直到处理到最后一个,无返回值 execplugin表示按顺序调用,但如果中间有函数返回非None时立即退出,并返回这个值
- 同时一个plugin调用点可以对应多个plugin的处理函数,是一对多的关系。这一点我在zca的例子中没有看得太清楚。
- 所以ulipad中的mixin技术不主要是为了组件的配置,更多的是为了功能的扩展,是合并,对处理,对类的扩展。如果说在ulipad中应用zca的话,要考虑:
如何使用zca对类进行扩展 如何处理callplugin和execplugin这两种机制
老潘注解
潘俊勇 <[email protected]> reply-to [email protected] to python-cn`CPyUG`华蟒用户组 <[email protected]> date Wed, Aug 27, 2008 at 15:49 subject [CPyUG:63620] Re: Python的组件架构扩展
On 8月27日, 下午3时29分, limodou <[email protected]> wrote:
> 不同的初始化将进行相应的组件的注册。然后在程序中通过象getUtility(IRelationalDatabase)之类的调用得到当时注册的对象进行处理。
恩,这个就是Utility,很简单的
> 因此只有当你程序有些组件需要考虑作成可替换,并且可配置时,使用zca是一个选择。
其实,不仅仅是可替换。可重用,以及简化也是。
多个相似的功能,用同一个接口抽象,对于接口的应用方,会简化很多。
这个也可以用相同的父类来处理。只是需要直接进行子类的初始化,代码的耦合会大很多。
>
> zca的注册,获取,配置的功能远大于interface。interface改为class也差不多,只不过interface可能有象java一样的检查功能,这一点可能要优于简单的class。但对于小项目是否这么做就不一定了。我之所以不喜欢java主要的一点就是规矩太多,而interface这个东西让我看到了java再现。可能对于大型的团队开发的意义要大于为了爱好而编程的小团体。
zope的interface不严格的,不需要和实现完全一致。偷懒的话,实际上你只需要写类名就可以了。 这个和java不同。
> ulipad的mixin机制与zca还是不同。使用zca,你是在程序只对其进行使用,并不是对当前的类进行扩展。而ulipad的mixin是可以对某个类的属性,方法进行扩展。而ulipad中的plugin工作方式与zca差不多。整个ulipad也有类似zca的注册,获取,配置的机制。不过我还不清楚zca中的plugin机制(类似这个的机制)是如果工作的,比如在ulipad中,你在某个类中定义了一个plugin调用,然后根据调用的不同api对plugin的处理有所区别:
对unipad不熟悉,但是适配的概念,可以让程序依赖扁平话,会很少出现多层的基层,耦合降低,程序更清晰,测试起来也更方便的。
其实熟悉设计模式的人会喜欢ZCA的。
看看Zope2就知道不用ZCA的问题。无数个父类,子类的功能无限膨胀,出现问题都不知道是哪里的了。
反馈
创建 by -- ZoomQuiet [2008-08-27 05:22:11]