To EJB Or Not To EJB, That Is A Question- -
我知道banq是EJB的忠实拥趸。这是他前不久的一篇文章:为什么要使用EJB?
这篇文章后来引发了Robbin与他的一场激烈论战,不过现在已经看不到战场,只剩滔滔江水。我得说,banq,在这件事上你确实显得小气了点。现在我已经看不到Robbin的言论,只好评价一下banq的文章了。
如果把基于POJO的方案称为“轻量级方案”,把基于EJB的方案称为“重量级方案”,应该不会有太多异议。用唯名论的眼光,名字本身就已经足以说明问题:一轻一重的方案各擅胜场。POJO方案的优点在于低开销、强大的灵活性和移植性(EJB环境同样是一种束缚,考虑不使用J2EE服务器时的情形)、开发成本低廉(调试和部署都非常简单);而弱点则在于分布能力,尤其是分布式事务的失位,使POJO方案在scalability方面有极大的欠缺。
banq说“EJB组件能提供真正的可重用框架”,这是一个彻头彻尾的误解(如果不是谎言的话)。在复用方面,EJB技术并不担保任何先天的优势。在同样的设计能力之下,EJB组件顶多具有与POJO组件对等的可复用性——如果不是因为EJB容器的限制而更差的话。EJB组件也只是一种大粒度对象组件,只不过EJB规范本身保证了某些契约的一致性,没有任何理由特别强调EJB的可复用性。
分层的问题也是一样:没有任何理由认为POJO方案特别容易导致层次之间的混淆。banq问“如果不使用EJB……如何保证在新的程序员不会破坏和打乱你精心布局的JavaBeans架构”,在我看来这个问题有所偏颇,因为EJB和POJO各有自己的一套东西需要遵守,如果不花时间来掌握这些规则,两种方案都做不出好的设计,过去的大量EJB anti-patterns已经充分证明了这一点。
一个需要澄清的误解:不使用EJB不等于“只使用JSP或者JavaBean”——当然,如果要把“JavaBean”这个词的外延无限扩大的话,你也可以这样说。实际上,结合IoC容器和AOP的支持,POJO方案同样可以提供crosscutting的infrastructure,并且这些支持是on-demand的。这里的重点在于:采用J2EE multi-tier体系结构的理由并不是要使用哪种技术,而是尽可能地获得能够完全无限制移植的业务组件——对于一个组织来说,业务逻辑是最可宝贵的,重复实现同一业务逻辑是最不可忍受的。而在“无限制的业务组件”这条路上,显然EJB走得并不是很好,它的侵入性太强了。同样是来自容器的侵入,Spring要求你提供一些setter,Pico要求你提供一些constructor,Avalon要求你实现一些接口,而EJB……你也可以认为它没有要求,因为这里已经没有“移植”这么一码事了。
与.NET社群不同,J2EE社群一向有着强大的民间生命力。鉴于Sun在J2EE领域的弱势(我们还记得EJB 1.0和JDO,以及Core J2EE Patterns 1st edition),完全追随官方推荐方案并不是一种明智的选择。而“TSS那些狂热的开源先生”,你不难发现正是他们推动着J2EE的发展方向——看看属于昨天的Struts、属于今天的Hibernate和属于明天的eXo吧。在我看来,除非有明确的scalability、distribution的需求,否则我会首先考虑基于POJO的轻量级方案。确实,将POJO适配成EJB是一件困难的任务,但从一整套EJB体系结构移植到POJO方案却是mission impossible。