随笔 - 3, 文章 - 0, 评论 - 16, 引用 - 0
数据加载中……
re: 简单说两句IoC和狗皮膏药 kjin101 2008-04-01 10:00
策略模式当然可以用IoC实现,我原贴里说的很清楚。但这只是策略模式一个侧面(解析策略object)的一种具体实现方式而已。策略模式完全可以用非IoC方式(比如directory lookup,singleton factory等等)来达到相同的实质目的(将算法或策略分解为独立object)。如果仅仅因为某一侧面的众多可能实现中的一种特定实现正好用到了IoC就将策略模式说成是IoC,那硬把冯诺伊曼架构和集成电路说成是一回事也不为过。

另一方面,IoC也可以被用来搭接很多以其它非策略模式分解的的应用。比如,IoC可以用来实现事件发生器和事件观测器的搭接,Object适配器的搭接,等等。如果IoC等同于策略模式,那么以同样的理由,IoC也等同于发布订阅模式,等同于适配器模式,等同于等等等等其他更多设计模式。。。最后硬把策略模式,IoC,以及发布订阅,适配器,等等等等通通混为一谈。。。是否也同样不为过呢?
> 不是很理解dynamic invocation proxies的意思,但pxgenproxy –h=foo.h > setup.xml这个命令行里的foo.h是必须的吗?

指定foo.h对pxgenproxy不是必须的,但对编译生成后的代码是必须的。-h=foo.h的目的只不过是让pxgenproxy将#include "foo.h"加入到生成代码中而已。

> 是必须的话那就离不开源代码了,至少是离不开头文件的。
> 这对于动态装载进来的、无法预知源代码或头文件的程序来说,
> 譬如说那些允许装载第三方插件的场合,就不太适用了。

foo.h只是头文件,不是源代码。这里,我们所真正要求的是提供class和函数的类型和签名声明。除了debug或脚本程序环境等少数特殊工具以外,绝大多数C++(甚至在ANSI-C)实际应用中并不存在要调用一个第三方class或函数而不知道函数的签名或class的声明的情况。我E文BLOG上讨论的就是这个问题。最重要的一点就是:IOC的实质目的并不是提供一个脚本环境,而是组件架构。你的目的若是需要调用C++库的脚本环境,请不要考虑POCOCAPSULE。

> 但是reflection却可以使用在这种场合。譬如说在一个 dll/so里,
> 装载进来时将reflection信息(class的名字、属性和方法)注册进某个
> factory之类的东西里,然后ioc container就能用class名字在factory
> 里找出并构造出那个class的实例,这个过程不需要头文件和pxgenproxy
> 这样的步骤。

关于reflection的陈述我完全同意。但IoC的实质目的(至少对于PocoCapsule IoC框架来说)与reflection并不相同。IoC完全不必照搬其他基于天然reflection机制的IoC框架实现。达到实质目的是最根本的。在我的E文BLOG文中比较了用reflection的缺点。。。。对绝大多数C++应用来说,reflection机制往往是有害的(主要是增加内存占用和限制开发方式。。。比如禁止了模板和宏的应用)

> vcf的reflection并不需要修改头文件,它要求加的那些宏是用来声明reflect
> 信息的,完全可以和class分隔开放在别的地方的,你对它的误解我想可能
> 是因为它的例子里把那些宏写在了class定义里头。

谢谢指正。但需要人肉写内些宏已经与使用IoC减少非业务逻辑代码的编写的除衷相矛盾了。

> 老实说,可能是受java的影响比较大,我自己并不喜欢pxgenproxy
> 这类带点源代码生成味道的东西,因为它会强迫你必须取得部分源代码,
> 这不适用于动态的开放的基于二进制层次的构件复用的环境。

pxgenproxy根本不需要任何源代码,也根本不会对使用第三方二进制模块造成任何障碍。pococapsule实例代码(见<http://www.pocomatic.com/docs/cpp-examples)中有很多这些例子。。。比如调用stdio中的printf(),调用iostream中的std::cout<<() operator,调用第三方CORBA或SOAP引擎函数等等。。。。

> 但是,像vcf这类的reflection其实还是依赖于源代码,
> 做得还是不彻底,因为c++编译后没有 meta data了。
> 可是c++ 0x不在乎这个,那我们也没辙。

IoC框架的目的不是为了提供debug或脚本环境,而是为了将管线逻辑分离并转移至框架内,并将让框架基于用户提供的声明式描述来完成管线搭接和应用的部署配置。对于此目的,reflection并不是必须的。相反,在C++中加入reflection将不可避免地增大内存开销,这对很多C++应用来说是致命的。所以,即使以后的C++升级加上了对reflection的支持(甚至CERN现在就有一个。。。请艘SEAL Reflex),PocoCapsule C++也不会考虑使用(同样的道理,PocoCapsule完全避免使用exception, template, rtti, stl, iostream等等机制和库,就是要尽量减少内存开销)。当然,PocoCapsule不会去禁止业务逻辑模块去使用这些机制或库。

多谢讨论!
是javaeye的suntoe吗?也是牛人呀。。。以后我可以多同你探讨和请教了。个人感觉VCF里的reflection太业余了,居然要求人肉修改poco的头文件。。。与非侵入思想背道而驰。IoC需要reflect才能实现才真正有用,这种认识完全是个误区。。。迷惑了很多人。。。事实上恰恰相反。。。在C++中如果真用reflection(比如CERN的Reflex)来实现IoC,所带来的问题反而比不用reflection多。我E文博客上探讨了一下这个问题(<http://ke-jin.blogspot.com/2008/02/dynamic-invocation-proxy-in-pococapsule.html>)。不过国内有可能上不了内个网,过几天我会把该文转到PocoCapsule的wiki上。。。。我说话也是逻辑乱跳。。。估计编程的都这德行。。。;)
>> 引用没有 const,指针有 const;

引用可以有const。
多谢捧场。。。这篇东西在别的地方曾经被几个老大斥责为很黄很暴力。。。嘿嘿。。。