解惑

解己之惑,解人之惑

分类:设计 (第2页共3页)

想重写JR的系统

一直都在考虑是否重写JR的系统,主要的原因就是目前JR的系统已经比较乱了,数据库方面的代码已经有三套了,由于没有写过单元测试的代码,因此全部更新
为一套是不太可能的;另外就是缓存的管理已经有些混乱了,有些是进行缓存的,有些没有,有些出于性能的考虑改用了自定义的缓存形式;想增加某些功能的时候
不太好加,因为对系统的损伤太大,这个已经在我的JR缓存系统的思考中提到过;页面的代码也不理想,重复的代码太多了,要进行某种改动,为了统一需要改动很多地方,这个也是历史遗留问题。

另外一个很重要的原因是想试验一下自己积累的代码,验证一下自己的一些想法。如果重写,肯定要重新设计一些底层的东西,简化类似系统的开发并且简化代码,争取消除大部分的重复代码(类似的问题在JIVE中也是同样存在)。

这段时间可能会整理一些想法,更加清晰的表达出来,也相当于进行设计了吧。

JR缓存系统的思考

最近增加的关键字功能可能会对JR系统的整体性能造成比较大的伤害,原因就是JR的系统中最值得称道的缓存功能的限制。
按照原来的情况,JR的缓存系统在90%的情况下会工作得很好,这个和系统的特点有关。
JR的用户,很多是按照我们的页面给出的顺序查看我们的内容,当然也有一些是通过各种搜索引擎搜索得到某个内容,但是按照比例而言,按照顺序浏览的可能比较多,因此大部分的人查看的内容都在缓存中,不在缓存中的内容会再到数据库取,因此系统的效率比较高。
而在增加了关键字功能后,关键字相关的文章列表中的内容很可能不在我们的缓存中,因此要把文章相关的内容都从数据库中取出来,这个时候缓存的功能就没有发挥应用的作用甚至成为了负担,因为缓存的内容的频繁交换在这种情况下做了很多无用功。

其实这个问题并非不能解决,甚至可以增加各种排序功能(按照目前的情况增加排序功能对系统的损害是致命的),方法就是改造缓存系统,将目前的单级缓存修改为多级缓存。
按照jive的缓存设计,每个被缓存的对象需要提供一个大小信息,而缓存管理器会维持一个大小受限的缓存池,如果采用二级缓存,内容的主要信息缓存下来(例如标题,作者,发布日期,回复数,最后更新日期,查看数,最后回复者等等),
而帖子的内容一级回复作为二级缓存的内容,按照一定的比例分配一级缓存和二级缓存的大小,而系统中经常查看的可能是内容列表而非内容,这样
缓存的功能就可以大大增加,即使把全部的帖子信息都缓存下来也是可能的,因为这个信息相对帖子的内容而言很小。
这个改造的难点在于缓存是系统的一个非常核心的功能,缓存相关的代码可能比较多,进行重构并不容易,当然应该是值得研究下的。

JR的关键字功能设计

目前JR的关键字功能比较简单,一个关键字实际上由并列的几个关键字构成,例如ioc,di以及控制反转都是作为同样的关键字对待的,每篇文章包含的每个
关键字都是有权重的,权重的算法目前也非常的简单,如果是标题中包含关键字,那么权重是出现的次数X关键字的长度X5,如果正文中包含关键字,那么权重是
出现的次数X关键字的长度,如果标题中包含某个关键字,那么正文中的同一关键字的权重将再乘以2,目前看,对于单一关键字这个权重的结果还是比较好的,基
本上能够反映出所有文章中和关键字的匹配程度。对于英文的单词,目前是全词匹配的,否则误判很高,例如di这个关键字,很多单词都包含这个字母序列,而我
们在判断是否包含关键字的时候都是转换为小写进行处理的。

目前正在开发中的是文章相关性功能,初步的设想是从原文章中取出其权重最高的五个关键字,然后看看其它的包含这些关键字的文章,其权重的和最高的就认为是
最相关的,目前看结果不是很理想,可能对于原文章中的关键字的权重大小不同对目前文章的关键字的权重进行相应的处理后得到的才能是比较好的结果。但是这个
也需要检验。

基于规则还是基于配置

一直一来都在思索为什么很多公司开发的产品都不好维护,也一直在思考如何设计一个可以快速开发和快速上手的框架,并且用该框架开发的东西要易于维护。
前几天在思考spring的IoC其实也并不是很好的解决方案,虽然他将类之间的依赖关系延迟到了运行时,做到了降低系统的偶合度,但是同时意味着对于一
个新人而言,它在理解这个系统的时候会存在很多问题,特别是系统的设计文档缺失或者不完善的情况下。国内的程序员似乎都不太喜欢写文档,有时候也认为代码
很简单,根本不需要文档,甚至很多连代码注释都没有,在这样的情况你如何希望别人可以很快入手呢?
前两天在改造我的JDBCTemplate的过程中,在完成数据的持久化时,突然想到与其基于配置,不如基于规则,符合规则的就可以通过,不符合的就不
行,例如从数据库取出的数据可以自动映射到javabean,数据库的命名使用下划线分隔,而转换到java的属性就是以下划线分隔的单词,除了第一个单
词外的其它的首字母大写,而对于表间关系,可以也按照命名规范来,对于一对多的关系,可以利用JDK5中的新的特性声明其类型完成。
在基于规则的情况下,配置会减少很多,但是文档依然是不可缺少的,不同的是文档要描述的主要是规则,而这个规则是框架的规则,新人需要研读的就是这个规则,他也不能写出不符合规则的程序,因为那样就不能工作。
有必要实际的检验一下这个想法。

避免多线程问题

在进行java开发的时候多线程问题很多时候似乎是无法避免的,而为了符合多线程的要求,我们往往要使用同步技术,而同步不光会大大的降低系统的性能,更
要命的是可能会出现死锁,而死锁的偶发性导致死锁问题难于追踪调试,当然也有一些解决死锁问题的技术,但是都难于使用,其实很多时候我们可以通过修改设计
来进行避免,设计时考虑的一个最有效而且简单的方法就是编写无状态的类,如果需要状态,那么这些有状态的类可以通过ThreadLocal进行管理,达到
线程安全并且复用的目的。无状态类的比较典型的例子就是spring中通过回调技术实现的数据持久层模板类。
最后需要说明的是,多线程问题不可能完全避免,但是在很多情况下是可以避免的。

需要根据Spring的要求重新省视自己的设计

利用周末的时间把中文版的spring参考手册中的现在需要关注的内容通读了一遍,原来我对自己的系统中考虑到的几个方面的内容spring已经提供了,
因此有必要完整的学习spring提供的内容,可能这次我有有点浮躁了,看来我要花一段时间把spring in
action也看一遍,可惜没有中文版的。现在也越来越懒了,不喜欢看英文原版了,可能是spring参考手册和hibernate参考手册翻译得不错的
缘故吧。

Spring中的多配置文件原来如此简单

一直都在找spring如何指定多个配置文件,因为一个系统一旦比较大以后所有的配置都放在一个文件中是非常不好的,不光是维护的问题,多人开发出现冲突
的可能性也就很大了,一直在搜索,但是没有什么结果,结果今天看了spring的参考手册(中文的那个1.1PR版)才发现非常的简单,在web.xml
中配置的时候直接指定多个文件就可以了,用空格、逗号或者分号分隔都可以,例如:
   <listener>
     
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>
   <context-param>
      <param-name>contextConfigLocation</param-name>
     
<param-value>/WEB-INF/configs/spring-config.xml
/WEB-INF/configs/db-config.xml</param-value>
   </context-param>

错误的选择了Xstream

今天突然发现我在做页面生成特别是进行Bean到xml的映射的时候错误的选择了Xstream,而我恰恰应该使用的是spring本身提供的功能,因为其实spring的XmlBeanFactory也可以达到相同的目的,所不同的是用spring稍微要复杂一些,但是这个复杂性是可以接受的,而且spring的子Bean功能是Xstream所没有的,避免了我再进行编码的工作。我对spring还是太不了解了,也许应该把spring参考手册完整的看一遍了。

使用XStream自动生成页面

找到XStream后我的页面自动生成的功能就完成一半了,思路基本上确定下来了:
主要是两个文件对页面的生成进行配置,一个就是配置系统中的Element,通常的表单中的一个输入项,例如用户名提示加后面的输入框以及有效性校验,这个在elements.xsl文件中定义一下就行了,然后另外有一个Form,对应一个完整的表单,同时也有一个forms.xsl配置文件,每个form有一个名字,form通过Element的ID进行引用,而且可以额外对引用的Element的缺省配置进行修改,然后JSP就可以根据配置从标准的FORM库里面取出配置好的Form生成页面的Form部分了,当然也可以用比较原始的方式从Elements库里面取出最小的单元手工拼装,然后这个Form可以和一个Bean绑定,完成Element的赋值。
当然这个只是一个思路,真正要完成这个还有很多的代码要写呢,不过有了这个已经比较好做了,剩下的就是生成页面的体力活了。

为什么java世界没有真正的快速开发平台

为什么java世界没有像微软的visual studio那样的快速开发平台,其中一个原因固然是因为微软封装了很多东西,提供了强大的集成工具并且要求你按照微软的设计思路来设计系统,但是java世界具备visual studio中的任何一种组件,所缺少的只是没有人或者厂商将他们集成起来,而之所以没有人去做,一个很大的原因恐怕是java里面每种组件我们都有太多的选择,web框架有struts,spring,webwork2以及其它的,ORM也有EJB,JDO以及hibernate,ibatis,obj供选择,IDE有JBuilder,Eclipse,IDEA,JDeveloper以及Netbeans,另外的其它的组件也是多得不可胜数,但是我们现在已经可以看到快速开发平台推出的希望了,首先是IDE的统一,Borland,BEA都放弃了开发自己的IDE转向Eclipse,而Eclipse3.1的功能和性能表现也足以吸引很多原来使用其它IDE的用户,而SUN的Netbeans一向不为大家所认可(SUN开发的大部分开发工具好像都是这个下场),因此有了IDE的统一,其它的组件基本上都可以围绕她来进行,加上Eclipse插件开发非常的方便,因此这更加促进了对它的扩展,而现在的情况也确实是向这个方向迅猛发展的。有了这个基础,我就来谈谈我对未来的这个快速开发平台的期望了(对于新开发的系统):

  1. 项目管理:可以使用maven或者ant,对于小一些的项目可以使用ant,对于项目管理的内容很多的可以考虑采用maven。
  2. 版本管理:基本上可以选定cvs。
  3. IDE:不用说,就是Eclipse了。
  4. 系统架构:以Spring为核心的架构应该是比较好的选择。
  5. 表现层:struts或者freemarker,这个可能选择性太多,除了struts外好像还没有哪一个有那么广泛的用户基础。
  6. ORM:Hibernate应该是现在的不二之选了。
  7. 辅助工具:xdoclet,可以根据项目的需要进行部分的内容的生成,减少很多手工的工作,也许应该有更多的缺省的扩展。
  8. 单元测试:Junit或者TestNG之类的,虽然有很多人说junit已经不那么好用了,但是对于一般的项目应该还是够用的。
  9. 。。。

其实还有很多其它的组件没有谈到,包括页面测试,报表,缓存等等,但是我这次想说的其实不是这些,我的核心其实是里面最不起眼的xdoclet,因为它其实可以作为所有这些组件的一个黏结剂,核心其实就是代码生成,我理想中的情况如下:

  1. 开发人员最初编写的就是一个POJO的属性列表,而这个属性列表的内容可能来自系统的设计文档或者其它的建模文档。
  2. 根据POJO的属性列表生成对应的POJO类
  3. 修改POJO,增加需要的hibernate或者其它的例如页面生成,spring配置需要的信息。
  4. 生成系统的完整骨架,包括spring配置文件,hibernate映射文件,JSP页面
  5. 修改生成的内容,对于细节的地方进行修改

依然很复杂,那么我们不妨再简单一些,编写POJO属性列表的时候增加hibernate配置信息,页面配置信息以及spring配置信息,一步到位生成全部的基础代码,或者是写一个这样的文件,点击右键,点击Generate target page…,在出现的对话框里面选择需要生成或者更新(覆盖)的对象,可以是hbm文件或者是页面文件或者是spring配置。
可能很多人觉得我是白痴,开发一个系统哪里这么简单,但是这样的一个系统已经为我们生成了系统的骨架,完成了很多烦琐的我们大部分人都不愿意做的枯燥工作,为什么不那样做呢?不管别人如何看,我会自己试验这样的系统的可行性的,也许是一个值得做的方向。
当然,一个复杂的系统的快速开发还远远不止这些,特别是系统要求是中型以上的系统,业务逻辑比较复杂,要求国际化,要求页面美观,易于修改定制等等,但是并非不可能,我们可以根据以前积累的经验定制一套这样的系统,例如ant+eclipse+spring+hibernate+freemarker+xdoclet+css,在系统组件的选择确定的情况下,我们甚至可以抛弃xdoclet使用自己完成的生成工具更好更灵活的的生成我们需要的内容。

更早的文章 更新的文章

© 2024 解惑

本主题由Anders Noren提供向上 ↑