1. 引言
搞Java的弟兄们肯定都想要达到更高的境界,用更少的代码解决更多的问题,用更清晰的结构为可能的传承和维护做准备。想想当初自己摸着石头过河,也看过不少人介绍的学习路线,十多年走过来多少还是有些收获。现通过自身经历总结一篇文章,供弟兄们参考。
2. 用好正在用的框架
在已经加入的团队中,和大家协作使用团队已选好的框架。不管框架优劣与否,特点如何,选择了它必然有一定的道理。并且能够在业界经久流行的框架也一定有它的优秀之处。
使用框架第一步是熟悉,可能通过复制和修改前人的代码来实现新的功能或修改已有功能,逐渐熟悉该框架的使用方法。
第二步是深入了解,会用、多用之后,根据用法和现象掌握其规律,从而形成对框架内部结构和运行机制的猜测,大部分肯定都是对的。
第三步是用好,在对框架内部机制有了一定的感觉后,逐渐总结并采用更佳实践,达到同样目的采用更简洁清晰或更高效率的方法。可以参考框架的“最佳实践”文档(比如Hibernate参考手册的最后一章),对没有提供“最佳实践”文档的可以自己总结一些经验,并不断完善。
没有绝对的最佳实践,只有适应于某一场景的最佳实践,和适用于大多数场合的较好实现。能够根据场景选择不同的模式,是水平提高的标志。
3. 了解标准类库、企业级技术和开源项目
Java界现有的积累已经很丰富,当遇到某个问题感觉它是个普遍问题时,很有可能就已经有现成的标准类库或开源项目等在那里了。掌握好标准类库和开源项目,可以减少工作量,使代码结构清晰容易理解。企业级技术是指JavaEE平台内的技术,其多是从已有积累中提炼出的标准,比如JPA就很大程度上来自于Hibernate。企业级技术的运用对程序的标准化很有好处。
对标准类库和开源项目的了解不分先后,可以是交叉进行的,用到了哪个就看看学学哪个。也可以用业余时间挑自己喜欢的学习学习、做做实验。
3.1. 标准类库
从Java自带的文档中可以看到标准类库(以及平台工具)的列表以及相互关系。下面这幅图就是层次关系图:
以挑自己感兴趣的点进去详细了解。
乍一看内容众多,但实际上可能已经有很多已经被用过了。比如JDBC,应该是每个Java程序员在涉世不深时就已经用过的了吧。JNDI应该也是做WEB工程必须接触的东西。也许只是其中几个API,不过什么都是了解、熟练、精通这三步,了解了,后面就不远。
其中规则表达式、XML处理、applet、并发(多线程)、网络、IO、图形是比较实用的功能,可以先从它们入手。本地接口(JNI)、管理扩展(JMX)、反射等可以用在更高级一些的场合,会了之后可以为更多的场景提供解决方案。
3.2. 企业级技术
包括JavaMail、JMS、EJB、JPA、JSF、web service等,具体的列表可以到JavaEE技术官网找到。这些技术用起来并不深奥,甚至比标准类库还浅显。
3.3. 开源项目
框架一般都是开源项目,目前拥有开源项目最多的组织莫过于Apache。可以通过需要来学习开源项目,比方说需要处理Excel文档,那就去学用POI;要用web service就看看CXF;需要字符串处理就看看Commons Lang中有没有实现;需要IO操作就看看Commons IO中有没有实现。
除了Apache,还有eclipse、springsource和Jboss等多家开源机构提供了大量的免费好货,有时间就去了解一下不失为进阶的好手段。“君子性非异也,善假于物也”——厉害的家伙不一定是什么都会自己写,而往往是会结合使用各种神器。
这里顺便说一句,很多开源项目都用了比较少见的英文单词或是自造词作为名字,遇到时最好去官网上确定它的读音。很多人吧Struts(原意:大摇大摆)读成了Structs,明显跟struct(结构)搞混了,听起来实在业余。还有PostgreSQL应读作postgres-QL,而不是postgre-SQL,请尊重作者的原意。Debian应读作“戴博伊恩”,是作者夫妇的名字合体,读成“大便”就太对不起人家了。Ubuntu也别读“优斑图”了。
4. 把程序写得更好
4.1. 代码格式整洁优雅
尽量遵循官网上的代码格式建议,善用开发工具(Eclipse)的自动格式化功能。
复杂的条件、循环嵌套提炼为方法,把方法名起得有意义,尽量让后人看程序就好像看直白的英文句子一样。追求代码自我注释。要注意尽量用单词别用拼音,特别是模块之间交互的接口(模块内部小范围使用的还好些),英语单词和拼音的混杂使用会让后人昏死。现在的电子词典品种繁多、易于使用,善用它们,让代码优雅的同时还可以多认识几个单词。
4.2. 代码内容高效
用过很多框架和开源项目并自己写了不少程序之后,可以开始考虑实践《Effective Java》中所讲的内容,何时何地如何运用合适的技术与机制。
5. 通过标准类库、企业级技术和开源项目了解模式
说到模式大家首先想到的可能是“设计模式”,有很多初学者为了进步也看了《设计模式》这本书,不过据我经验,当时看不懂,不知道那些模式为何存在,也不知道何时可以用上它们。实际上所谓“模式”不过是前人的习惯用法,被后人认为好用并广泛流传。所有将前人代码复制过来改一改就用的,这样的代码其实都可以说是某种“模式”的实现。
有了对标准类库、企业级技术和一些开源项目的运用后,模式的感觉才会在头脑中建立。这些类库、技术、项目本身实现了很多模式,对它们的使用也是模式。只不过后者常被称为实战,而并没有当做“模式”出现在出版物中。
“模式”除了《设计模式》包括《企业应用架构模式》、《J2EE核心模式》,也许还有更多其它的。标准类库和开源项目(包括很多流行框架),出于设计的灵活性、便捷性、优雅性,对它们有杰出的运用。
Spring就是对工厂模式的实现。JDBC和JMS是对抽象工厂方法模式的实现。
Struts除了大家皆知的MVC,其实还实现了J2EE核心模式中的好几样。
Hibernate内部使用了Proxy模式,而它整体的存在是《企业应用架构模式》中“表数据入口”的实现。而老的EJB2.0中的CMB更像是“行数据入口”的实现。
这些模式直接当做概念来学习,没有实际经验,就会像我当初一样不知它们为何存在也不知如何运用它们,事倍功半。
现成的产品用多了就有感觉了。感受它们带来的方便,将它们中功能相似的互相比较,就可以看得出各种模式的存在和它们的优秀之处了。
6. 了解面向对象的真谛
了解了模式,就会发现实现这些模式的根基正是面向对象提供的封装、多态这些特性,这也是面向对象出现的意义。
面向对象的八大原则在《敏捷软件开发——原则、模式与实践》中有所介绍,其中我最看重“单一职责”原则,这个原则在模块划分时很有帮助,其思想甚至可以延伸到组织结构的建设上。
7. 展望——架构师
有了以上几步,应该就可以作为一个合格的设计人员而存在了。想做到架构师,曾经有位培训师告诉我们:“学习Linux内核。”
大的步骤是:看0.01版了解其结构,看0.10版了解其进步,看0.12版了解其完善,看最新版了解其现状。
学习方法是使用UML工具,对下载的Linux内核源文件进行反向工程,从得到的类图中可以看出模块依赖关系,出度最大的模块就是系统的核心,从这个模块看起,看它如何调度其它各个模块,再去看各模块如何实现自己的功能。
8. 结语
这些步骤并没有严格的界限,可以穿插、迭代地进行。
学习是一个先发散后收敛的过程。开始好像面对一个扇形,越往外走发现不会的越多,需要学的越多。但到了后来就会发现学过的东西相通之处很多,新看的东西能够快速理解,甚至能够发现有些东西不过是新瓶装旧酒,看两眼就会了。
“愚者察异,智者察同”,愚人看到事物各有不同就觉得世界难以掌握,而智者善于看到事物间的共同点(规律)以使事半功倍。既然程序员都干得了就别当自己是个愚者。