当前位置:   article > 正文

从Jive2到JiveJdon3看OO发展轨迹_oo反模式

oo反模式
从Jive2到JiveJdon3看OO发展轨迹

板桥里人 http://www.jdon.com 2007/07/9

  OO面向对象概念虽然出现很久,但是其间也经过较长的不断完善和发展过程,这也是很多初学者总是有“只闻其声,不见其影”的疑惑, 下面从Jive论坛这个缩影来看看OO思想和技术的发展轨迹,从而说明今天OO已经全面进入成熟普及阶段。

  论坛软件可能很多搞企业开发的人不一定看得上,认为不算复杂很简单,其实论坛软件作为社区软件的主体部分,它也象ERP或财务软件一样, 是和人类组织互动非常紧密频繁的软件代表,论坛软件可简单,也可复杂,麻雀虽小,五脏俱全。

  由于论坛功能很多程序员非常熟悉,这就不象财务ERP软件,了解这些软件首先需要学习财务管理知识,这样论坛软件就容易成为初学者 学习研磨纯软件技术的最好载体。

  谈起java论坛软件,比较著名或者可以称为经典祖师爷就应该首推Jive,Jive前身是开源项目yazd(http://sourceforge.net/projects/yazd),后来作者 将yazd商业化后改名为Jive,并成立Jivesoftware.com支持,虽然Jive是商业软件,但是2002年Jive2.0/2.5还是可以使用CVS直接下载源码观摩,Jive2在 架构上基本遵循yazd的设计,只是在功能增强拓展,而且还惊奇地发现,yazd也在发展,今年推出了yazd3.0版本。 Jive论坛如今已经被广泛应用到很多著名领域,例如SUN的Java论坛(http://forum.java.sun.com),多年来运行已经证明Jive架构设计的成熟性。

Jive2优缺点
  Jive软件最大特色有两个:OO和缓存。OO体现在大量使用了GoF设计模式,因此,Jive源码也是我们学习OO设计模式典范,笔者曾经在自己的书籍“java实用系统开发指南” 中专门对其进行了架构解剖和分析(http://www.jdon.com/idea/jive/03002.htm)。

  但是,由于OO技术本身当时处于发展之中,因此2002年的Jive2也暴露了OO一些问题和有待改进的地方。例如:jive2设计的时候没有修改帖子的功能,这倒不能怪罪Jive2,因为jive2不可能将所有功能一次性全部提供,看来我们只能自己给Jive2增加帖子修改功能了。

   现在软件的致命问题来了,通过了解Jive2架构和源码后,竟然发现增加“帖子修改“功能不是一件简单的事情,可以说非常麻烦(http://www.jdon.com/jivejdon/thread/32220.html),如果一个软件在拓展维护时很困难,可以说这是软件致命问题,这也是我们为什么使用OO目的所在。也就是说,虽然Jive2使用OO设计,但是还是没有真正达到OO使用目的:易于维护易于拓展。

  那么问题出在哪里?这时很多人都开始怀疑OO到底有没有作用,但是我们不能想想:是否OO得还不够?我们还是从新增“修改帖子”这个功能作为切入点,谈谈Jive2在OO上不足之处:

  Jive2主要对象有三个:Forum ForumThread ForumMessage,它们类图如下:

jive

  ForumMessage表示一个具体帖子,ForumThread是代表帖子集合概念,表示有关一个主题(也称根贴:rooMessage)的一系列帖子的组织结构, 新增或删除一个帖子,会对帖子组织结构有影响,ForumMessage新增和删除都和ForumThread有关,但是帖子修改如果修改的是内容,那么 就不会影响到帖子的组织结构,所以,帖子修改就可能和ForumThread无关(除非搬迁帖子)。

  深入研究Jive2结构后,会发现帖子ForumMessage新增和ForumThread新增 功能是在ForumFactory中实现的,如下代码:

 

public abstract ForumThread createThread(ForumMessage rootMessage) throws
UnauthorizedException;

/**
* Factory method to create a message with an anonymous author.
*/
public abstract ForumMessage createMessage();

 

  ForumFactory是Forum工厂模式实现,用于Forum论坛的创新和维护,结构图如下:

jivefacory

  ForumFactory作为Forum的工厂类,不仅管理Forum创建,也负责ForumThread和ForumMessage的创建,管的事情真不少啊,看来, 我们只能将帖子修改功能放在ForumFactory中了,这就带来一个架构上大疑问:以后关于帖子的更多功能是否加在这个ForumFactory中?这样下去,ForumFactory变得多大多重啊?从设计上讲:很多功能耦合在一个类中,这和面向过程中主函数有什么区别?维护拓展 更不方便啊,这虽然符合Facade或工厂模式,但是却走到模式的对立面去了,是反模式了。

  前面提到过Jive前身Yazd也在发展,推出Yazd3.0,那么Yazd是如何解决这个问题呢?打开Yazd源码会发现,Yazd设计者是讲帖子创建 放在了Forum中,而不是ForumFactory中。

  从这里也可以看到了不同设计者在同一个架构下的分歧:不只是对Forum和ForumFactory的认识分歧,更深层次反应了Jive/Yazd基础架构上设计上的缺陷,因为不管是放在ForumFactory还是Forum中,帖子的新增和修改是围绕ForumMessage展开的, 和Forum对象都有些距离,而且所有功能都塞入一个大类中(Forum或ForumFactory),拓展维护都存在大问题。

  Jive2竟然无处适合增加“帖子修改”这一简单功能,这就是Jive2架构的最大缺点。

解决方式探讨

  那么我们是否可建立一个ForumMessageFactory专门用来放置围绕ForumMessage的新增修改功能呢?但是带来的问题是:ForumMessageFactory这个新类 如何纳入Jive2原来的权限体系中,因为从前面ForumFactory结构图中我们看到:Jive2是通过一个唯一的ForumFactory来掌控客户端JSP访问权限,实际 就是通过ForumFactoryProxy这个权限代理类实现。

  Jive2使用代理模式实现权限的缺陷是:一个原始类对应一个权限代理类,一个Forum有一个Forumproxy; 一个ForumThread对应一个ForumThreadProxy;一个ForumMessage对应一个ForumMessageProxy,这样下去,类似的代码类何其复杂而庞杂,这样复杂结构 反而导致系统难于阅读和维护,这是有人将复杂性归于模式,因为模式带来了复杂。

  是不是这样呢?这种观点只是看到表面,没有看到实质,造成Jive2权限体系如此复杂原因不在于使用了模式,而是误用了模式,也就是模式选择不恰当,或者 说有待改进,代理模式的使用方向是正确的,但是导致一个原始类对应一个代理类复杂局面说明有待改进,我们从另外一个纵向方向会发现,这么多代理类不是没有共性, 有一个共性是:都是关于权限的代理类,虽然代理类有很多,但是都是关于权限方面的,那么能不能从权限方面将这些多个代理类合并为一个代理类呢?

OO革命飞跃

  答案是肯定的,使用动态代理,也就是说这涉及到了最新OO设计理念:AOP(面向方面编程http://www.jdon.com/AOPdesign/jdon-aop.htm)。 原来Jive2的不足就在于权限虽然和业务进行了分离,但是属于藕断丝连,而且使用了简单的代理模式更趋复杂, 如果我们使用AOP就可以实现权限和业务的彻底分离,从而使得我们为系统增加新功能时更加方便,易于拓展,真正实现使用OO目的。 当然,无论引入AOP还是动态代理,都需要一个动态代理或AOP框架,2004年以后出现的Spring或JdonFramework以及EJB3都是这样框架。

  下面我们回到增加“帖子修改”这个功能设计主线索上来,前面说了,帖子的新增和修改功能做好是加在ForumMessageFactory这样一个新的功能类中,那么我们探讨ForumMessageFactory类的设计合理性,这是一个工厂类,一般封装对象创建过程,比如帖子的新增,但是帖子的修改则不属于对象创建, 如果封装到ForumMessageFactory工厂类中有些牵强,那么将帖子修改功能放入一个新的管理者类ForumMessageManager?

  现在小结一下:我们发现围绕每个实体对象如ForumMessage,都会有一些管理者,这些管理者代表表示一些行为,是一种动词性质。

   在实践中,发现这种现象后我们需要两种武器:一种是支持这种现象结果的分析方法;一种是如何对这些管理者动作类进行松耦合设计管理?

  首先,对于第一种武器,2004年出现的Evans DDD为我们分析得出上述现象结果提供了方法理论支持,DDD认为上述现象其实是实体模型(ForumMessage)和服务(ForumMessageService), 当然还有值对象,这些组成领域核心层,我们尽可能将业务逻辑使用实体对象或值对象来表达。

  对于第二个课题的解决方式,也就是解决服务之间的松耦合,2004年提出的Ioc或称DI模式提供了解决方案,正如我当初2004年预料那样,DI已经成为新一代 软件的设计基础,无论从Spring EJB3 Struts2.0 JBoss Seam都是基于Ioc的全新架构,正是引入了DI模式,这些技术几乎都要从底层重新架构,这些全新架构如今 影响着我们使用的每一个新技术。

重写Jive2

  既然Ioc或称DI,以及前面的AOP正是解决象Jive2这样传统的OO系统不足而提出的,那么Jive2这样软件就有理由使用Ioc/AOP重新架构,这样,当我们增加“帖子修改”这个 新功能时,才方便容易,而且有理有据。

  正是基于这些想法,我本人决心重新重写Jive2,首先需要一个Ioc/AOP框架,当然使用Spring无疑是一个选择,但是个人认为Spring的DI进行手工定义有些烦琐,不能引入新 设计导致更复杂,虽然它的AOP很强大,但是实战中,象Jive2可能就需要一两个实现权限的AOP拦截器就可以了,强大灵活又意味着复杂,能不能设计一种适合Jive2这样中小型 系统简单好用的Ioc/AOP框架呢?同时又能保持Jive2缓存高性能这样的优点呢?2004年我设计开发了JdonFramework(http://www.jdon.com/jdonframework/)。

  有了Ioc/AOP框架,我们就可以基于JdonFramework全新开发类似Jive2新的论坛,这就是JiveJdon3.0来历(http://www.jdon.com/jdonframework/jivejdon3/index.html)。

  现在我们再回到主线索,使用JiveJdon3.0是如何方便实现“帖子修改”这样新增功能呢?

  首先,JiveJdon3.0由于采取了MVC框架Struts,实现java代码和Jsp页面的分离,这样JiveJdon3.0的Jsp页面就不像Jive2那样混乱,Java代码和Html混乱在一起,大量if语句混淆其中,使得 有关页面维护变得非常困难,如果 不能完全理解Jive2某个Jsp的完整意义,都无法修改,别谈增加新功能了。

   原来Jive2的Jsp嵌入了很多权限判断代码,比如post.jsp中就有判断只有注册用户才能访问post.jsp权限,这些都导致Jive2的jsp异常复杂,在JiveJdon3中,我们引入了JavaEE的标准机制: 基于容器的安全机制(类似Spring的Acegi),使用JavaEE服务器提供jsp页面访问授权功能,这样,在Jsp中就无需Jive2的Jsp那样冗长权限判断代码。 实现权限和表现层控制的分离。

  在JiveJdon3.0中,帖子新增和修改功能是在ForumMessageService(类似前面的ForumMessageManager)中,代码见com.jdon.jivejdon.service.ForumMessageService中。

  那么ForumMessageService中的权限是如何解决呢? 我们是通过引入AOP拦截器com.jdon.jivejdon.auth.PermissionInterceptor以及com.jdon.jivejdon.service.imp.message.ForumMessageShell代码从两个方面解决。

   拦截器是按照权限规则配置执行的,相当于在运行时刻生成Forum的ForumProxy对象,ForumThread的ForumThreadProxy对象,以及ForumMessage的ForumMessageProxy对象, 不必象Jive2那样,需要N多个权限代理类,增加代码的复杂性。在JiveJdon3中权限配置文件中定义如下:

 

<service ref="forumMessageService">

   <method name="createTopicMessage">
      <role>User</role>
   </method>

   <method name="updateMessage">
      <role>User</role>
      <role>Moderator</role>
      <role>Admin</role>
   </method>
</service>

 

  这就相当于Jive2中ForumFactoryProxy中createMessage方法代码,使用XML配置规则替代Java源码,简化代码结构,降低复杂性, 而且便于修改和维护。

总结

  以上从Jive2到JiveJdon3发展变迁,总结了OO本身的发展历史,我们是从一个小小功能增加方便与否来衡量一个软件质量是否够好? 这可能改变很多初学者对软件的概念,他们起初误以为软件就是实现功能,只要功能能够实现,软件就OK了,如果真这样,软件本身就 无需发展了,从中我们可以看到,现代业软件的发展重点不是功能能够完成,而是新功能能够迅速增加,软件是否更易于维护,这些才是 驱动软件继续发展的动力,才是面向对象OO思想和技术诞生的原因,才是我们必须抛弃面向过程和面向SQL数据库编程习惯的根本原因。

  虽然,Jive2在2002年就走上了OO路线,抛弃了数据库路线(Jive2中数据库实现DbForum只是作为Forum一个具体实现子类),但是由于OO思想当初 不够成熟,还有很多问题有待解决和发展,Jive2是那个OO时代的代表,知史而晓今。我们从Jive2的欠缺就知道今天热门框架流行的原因。

  在现在OO思想和技术已经充分发展和成熟使用的今天,我们已经再没有理由因为OO在不断发展而排斥它,特别我们国内软件,大量都停留在 数据库软件和面向过程旧时代,还处于Jive2出现之前的那个时代,这些都不能不让我们中国程序员的有识之士焦虑和担忧啊!

发表讨论...

相关讨论:

如何成为Java高手

Jive论坛

Jive论坛与Spring框架

面向对象与领域建模

DDD(Domain-Driven Design领域驱动设计)实战

Java项目开发中常见根本性认识误区

领域模型驱动设计(DDD)之模型提炼

Java EE/J2EE面向对象编程之道

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/884059
推荐阅读
相关标签
  

闽ICP备14008679号