很久没写月总结了,主要是由于近半年的积累主要在研究jfinal和扩展jfinal-ext上。等年会过了再好好做年度总结。这里先简单做一下最近个月的总结。
一 jfinal让我懂得的事情。
首先是一个简单易用的框架,一个微内核高扩展的良好架构。经过半年的使用和一些思考,慢慢领悟了一些思想。
1 代码量要少。
为什么要强调这个。因为代码量少让你很容易看完源码,利用源码调试也很方便。之前用struts2调试一个action not found的错误,点了半天源码我就退缩了。。而12月也遇到一个诡异的action not found的问题,走了一下jfinal的源码就很快解决了.
代码量少在维护期间是有很大的优势的,比如我们经常遇到数据模型的修改,用ar的模式就是只用改数据库,不会引入复杂度,修改的代码全是有用的业务代码了。利用get set虽然能带来静态代码提示和检查的优势,在项目建立原型的阶段甚至可以利用生成工具快速生产,但是维护阶段的添加是很麻烦的,之前用一些生成ssh项目架构的工具深有体会,个人无法忍受重复的无意义的劳动
框架代码少那么即便是框架本身出问题了,也会很容易解决,因为它本身没用引入过多复杂度。
2 基于最基础技术做最强大的功能
虽然一直没时间仔仔细细读完jfinal源码,只是在有需要的时候度过局部的代码.但是总体感觉是并没用引入很多“高级”的技巧.只使用少量的注解和反射,动态代理也只有一处,jdbc元编程也用的很简单。这样的其实是很智慧的做法。尽量的不引入“高级”用法,让新手尽量减少新概念的学习,比如用ssh那里面就用了xml解析,字节码生成。要真正理解这些框架的实现那需要学习的东西就太多了。而jfinal则不一样,我相信要读懂源码不是很困难,而且新手在引导下也很容易理解,我准备利用空余时间做jfinal的源码赏析的内部培训,做这样的尝试,让大家都真正彻底掌控这个框架。
由于技术够基础,框架够简单,我试验让新人在完全不接受系统讲解的情况下通过看demo和文档做crud,效果还是比较理想的。因为基础的功能会sql就能做业务了,只要有javase和sql基础。1年前做一个项目采用生成工具,让3个新人看文档去做,效果不是太理想,就算是生成了之后再修改代码,那个也是挺困难的。因为框架本身的复杂度没降低,生成了复杂的重复代码,在开发途中模型修改要重复生成代码的时候,有很多问题,就要生成器做如何覆盖的策略了,经常吧改过的需要的代码重生成的时候覆盖了。。。。当然我自己还是认为生成器是有价值的。在java这样的元编程不是很强大的语言里,有些东西是不能复用的,所以理想的情况就是用生成器生成一个利用简单框架实现的基础功能。然后在开发过程中就尽量不用生成了。目前正准备着手开发利用jfinal的架构弄一个,并且教给新手去做。因为真的太简单了。。
3 尽量不要改变开发者已有习惯
这个其实和上一点是差不多的,只不过上面说的是要减少代码的复杂读,而这里讲的要减少开发者使用的复杂度。其实第一接触这样的full stack框架是在3年前,刚在学校学习java不久就了解了groovy也用过grails。1年前也了解了play之内的东西,最后都没有坚持去使用,一是感觉要各种命令行和插件,很烦,我承认我很懒。还有更多要考虑团队其他人的接受度,记得以前在公司用jhi生成项目的时候,主管就说你不能把每个人都想象成你,不是每个人都愿意去学习新东西的。包括今年给以前主管推荐jfinal的时候,他也说新手就不要去改变他们的已有习惯了,他们用那些都习惯了什么的。 如果现在回到那个时候,如果有充足的时间,我相信我会用jfianl+自己开发一个简单生成器去带新人项目了吧。
这里提的这点,我相信作者是经过很多思考的,怎么去推广自己的作品,怎么去让人容易接受,那么就是尽量不改变已有习惯,不用装什么其他的东西,尽量的轻巧和易启动吧。我自己最开始也是由于jfianl demo一下子就跑起来了慢慢去接触的。
二 试一试clojure
由于越来越懒,对重复的东西无法忍受,喜欢去做各种能重用的东西。在这个过程中受到很多语言本身的限制,特别是在用了一些其他语言之后更是无法忍受java蛋疼罗嗦的语法。又有同事在生产环境用clojure,所以有比较好的条件去学习.clojure是一个jvm上的lisp方言.由于开始讨厌限制,喜欢更加自由而有创造力的开发,在空余的时间出了继续研究和扩展jfinal之外就多花时间学学这玩意儿。
在java里面要玩各种魔法需要玩各种字节码工具和自定义类加载器,这个程度已经玩的很熟悉了。前几周甚至还想去使用一下ejc来动态生成代码让eclipse提示,不过真不简单。。。
既然想要在一个静态语言里面突破各种限制达到动态的效果,干嘛不用动态语言呢。。既然要突破各种语言的限制,那么怎么不用限制少的语言呢.. 这也是我决定尝试clojure的原因。
三 最近遇到的坑
1 messageformat
因为一些历史原因和最初的设计不足,代码里面有类似这样的一个字符串替换了
String msg = MessageFormat.format("select * from user where id in({0})", id);
接受id的是一个long类型.
之前都一直好好的,然后突然有一天开始报错了。。我调试一看,原来是超了1000的id用千分号了,导致拼出来的sql错误了...然后把id加个""解决
2 oracle的时间类型
已经无力吐槽oracle了,,ojdbc14和ojdbc6对时间处理的行为不一样. 在oracle的时间类型上被坑了无数次。
oracle返回的不是标准的java的时间类型而是自己驱动的类型.导致很多第三方的东西处理有问题,比如freemaker只能处理java的时间类型,对ojdbc14的时间类型只能显示一个无可读性的对象引用的字符串,,而ojdbc6的确能显示出一个可读的时间格式,但用freemaker却不能格式化。。所以必须在代码里面转换oracle的时间为java的时间..详细见http://www.oschina.net/question/203191_61937
另外遇到一些诡异的问题,数据库类型是date,但是在有些情况下从驱动查询返回的类型确是timestamp..有时候返回是java.util.date. 之前大概分析出一些原因,ojdbc14貌似是添加记录的时候用timestamp,即便数据库类型是date返回也是timestamp,而ojdbc6确是无论什么类型返回都是timestamp.
本来这里我是想自己再做一些实验把所有情况试一试列一个表格的,但是这时候测试ojdbc14的时候发现无论怎么都返回java.sql.date了.......果断对这个实验没耐心了,
总结一点都用timestamp吧。。免得麻烦。。