1995 年 5 月 23 日,Java 语言正式诞生,1996 年 1 月,JDK1.0 发布;2000 年 5 月,JDK1.3、JDK1.4 相继发布;2004 年 9 月,J2SE 1.5 发布;2009 年 12 月,Java EE 6 发布;2014 年 3 月 18 日,Java SE 8 发布。19 年的历史,Java 已经成为全球最流行的开发语言之一,也是使用最为广泛的企业级语言,没有之一。在软件开发的世界里,两年一小变,三年一大变,QCon 北京 2014 大会上,来自 ThoughtWorks 的首席咨询师郑晔回顾了最近十多年软件开发领域的发展变化,并重点介绍了 Java 世界程序库、开发方式、工具等的变化。会后,InfoQ 对郑晔做了一次深入专访。
InfoQ:为什么会在这次 QCon 演讲上选择“你应该更新的 Java 知识”这样一个话题?
郑晔:这个话题可能与我个人的经历有关。我的职业生涯是从 Java 起步的,中间各种机缘,我做了很多其它不同类型的项目,接触过各种各样的程序设计语言。最近几年又重新把所有的注意力放回 Java,我很惊讶地发现,现在许多程序员讨论的内容几乎和我十多年前刚开始做 Java 时几乎完全一样。要知道,我们生存的这个行业号称是变化飞快的。 其实,这十几年时间,在开发领域已经有了非常多的新内容涌现出来,即便是 Java 开发这个领域,也有了很多变化。我自己最近的几个 Java 项目,用到了不少十年前没有的东西。既然我有了这样的感觉,为什么不能尝试着总结一下呢? 于是,去年我在自己的 blog 上写了一个系列的《你应该更新的 Java 知识》。我自己真正总结出来的内容要远比写下来的多,在公司内部,我做了一个有十几节的课程,给自己的同事分享过。这次的 QCon 分享的主题,就是基于这个系列课程第一讲的概述部分。所以,我在演讲上也提到,如果想了解全部内容,就看以后还有没有机会在更多的大会上分享了,当然,如果想更完整地了解,可以专门联系我,呵呵。
InfoQ:在演讲中您提到,您向大家推荐了很多比较好用的 Java 开源软件,比如 Guava,能详细说说吗?
郑晔:我推荐的程序库有一个的原则,它们必须有很易用的 API,而不仅仅为了实现功能。下面是我在演讲里列出的几个我愿意推荐给大家的程序库。
我对 Guava 的一个评价是,只要你做的是 Java 项目,就应该用 Guava。Guava 某种程度上是弥补了 JDK 的不足,我们都知道,JDK 是为了给 Java 开发人员提供一个基础的开发包,但是,JDK 基本上定位于功能实现。这在 10 多年前,没有问题,但现在,随着人们对于代码编写认识的加深,仅仅有功能已经不够了,还要有一个易用的接口。举个简单的例子,把文件读到一个字符串里,如果用 JDK 实现,光想着异常处理都回让人头疼不已。Guava 是一个现代的程序库,它有着更易用的 API。当然,Guava 也有一些新增功能,比如,一些集合类、缓存等等。Guava 做得怎么样?看一下 Java 8 的文档就可以知道,有一些 API 几乎就是原封不动地从 Guava 上借鉴来的。
Joda Time 是我提到的另一个程序库。它现在的位置很有趣,我们都知道 JDK 中原有的日期库设计的非常糟糕,Joda Time 就是为了让我们躲开 Java 的日期库。但是,因为它设计得很好,它也被 JDK 借鉴了,于是有了 JSR 310,现在已经是 Java 8 的一部分。不过,从技术发展来看,Java 8 广泛使用起来还有很长的路要走。大多数人还会继续与 Java 6 做斗争,所以,我还是把它列了出来。
Hamcrest 和 Mockito,是两个用来测试的库。Hamcrest 让我们更好地写断言,而 Mockito 让我们更好地编写 Mock 对象。
DropWizard,我们可以把它理解一个开发 REST 服务的框架,但其实它什么都没做,只是把一些已有框架集成到了一起。它同前面几个程序库有很大的不同,它更多地是代表了一种的开放方式:轻量级部署风格,抛开沉重的应用服务器。它未必会是未来的赢家,但值得了解。
其实,还有一些不错的程序库值得推荐,比如,像实现了 Actor 的 Akka,但这些库往往是代表了一种特定的程序设计风格,所以,我没有特意列出。 近些年,Java 世界里出现的“新”工具“新”框架,在学习这些工具框架方面,您有什么好的方法提供给大家?
InfoQ:对于这些新工具、新框架的学习,您有什么好的方法分享给大家?
郑晔:软件开发行业是一个发展变化很快的行业,尽管很多思想层面的东西变动不大,但在具体操作层面上,总会有新的东西层出不穷。作为一个程序员,如果不希望为这个时代淘汰,一个开放的心态必不可少。就我个人而言,我会一直开着自己的雷达,了解各种新技术、新知识的。至于到具体的工具框架学习,没有什么特别的,文档是最好的老师。基本上,文档会把功能性的东西都告诉你。
InfoQ:在实际的开发中,同一个功能往往有不同的框架做了实现,比如 MVC 的实现就有 Struts、SpringMVC 等。在遇到类似的情况时,您是怎么选择框架的?
郑晔:在功能类似的情况下,我会选择更符合技术发展方向、API 设计更好的库。
举个例子,如果开发一个 Web 应用,以前的做法是用 Spring MVC 一个一个页面写,但现在我不会这么做了。我会倾向于基于微服务的架构,这是一个符合技术发展方向的做法。更容易理解的说法是,后台提供基于 REST 的 API,由前台页面进行访问。这样原来传统的方式就显得笨拙了,它们是为了由后台渲染页面准备的,所以,后台框架我会选择一个更容易做 REST API 的框架,比如用 Jersey 加上 Jackson。
再举一个 API 影响选型的例子,我们常用的 Log 库,以前我们都会选择 Commons Logging,但是使用这个库,通常我们的代码都是在正式地写日志之前,先判断一下 isXXXEnabled。因为这个库是 Java 5 之前设计的,之所以这么做,有许多性能之类的考量。而现在,我的首选 Log 库是 SLF4J,就省去了那些不必要的代码,非常清爽。
InfoQ:在演讲中,你还重点讲了自动化。那么,在这方面您是怎么做的?
郑晔:对于自动化,我的基本理念是,尽可能自动化一切能够自动化的东西。十几年前,我们提到自动化,基本上就是编译、打包,而现在自动化的范围比以前大得多。我在 2011 年曾在 InfoQ 上发表了一篇名为《软件开发地基》的文章,里面谈到了我在项目里所做的一些基本的自动化工作。时隔三年再来看这篇文章,大部分内容依然是适用的。而现在,当我们谈到自动化,应该比那篇文章的范围还大,在我自己的项目里面,我们会把一些环境部署的过程也自动化起来,按照现在流行的说法,目标是要做持续交付。
在 Java 自动化领域,最近几年一个比较大的变化发生在工具领域。我在演讲中提到了,如果你现在还在用 Ant 和 Maven,你就落伍了,Ant 做简单的事不简单,Maven 做复杂的事情很困难。现在的趋势是,以全功能语言做自动化脚本。《软件开发地基》那篇文章里,我用的工具是 buildr,它依赖于 Ruby 语言。最近几年 Java 领域表现最活跃的自动化工具是 Gradle,它现在几乎是我做 Java 项目的默认之选,其基础是 Groovy。
InfoQ:您讲到轻量级部署相关的一些建议,能详细说说吗?
郑晔:一说起 Java 应用的部署,大家直觉上就会想到“打个包,部署到应用服务器”。这也是几乎十多年前就定型下来的开发方式。但对于开发人员来说,这就几乎就意味着各种开发的噩梦。为了在开发阶段定位一些问题,我们就不得不在“本地”进行用上“远程”调试。
应用服务器是一个“老大哥”年代的产物,那时候大公司要卖应用服务器,更要卖硬件,所以,它们炮制出复杂的业务场景。但是,对于许多团队来说,你可能一辈子都碰不到这样复杂的情况。当年,EJB 的破产已经让我们见识了这种虚幻的需求在程序员社区里是站不住脚的。现在,轮到应用服务器本身了。我在演讲里曾经举过一个例子,说明这个应用服务器中一个虚幻的需求,在一台应用服务器上部署多个应用。现在我们看到,大多数应用多个应用服务器都不够,一个应用服务器部署多个应用除了测试玩玩,在实际的场景中,几乎就是站不住脚的。开源社区的兴起让普通程序员有机会见到高手是如何工作的,高水平程序员总会追求更“简单”的工作方式,吸引更多程序员走入这种方式中。我很高兴地看到,我们的开发方式不再是由老大哥主导了。
最近几年,随着云和移动开发的兴起,微服务的概念逐渐进入了我们的视野,随之而来的就是社区对于开发和部署的反思。前面提到的 DropWizard 的就是一个很好的例子,通过它,我们只要打出一个 JAR 包,和传统的方式不同的是,这个 JAR 包直接就是一个可运行的应用。是的,它是有 Main 函数的。有 Main 函数就意味着,我们可以很方便地在 IDE 里做我们想做的一切,包括调试。这样一来,对比从前那种笨拙的方式,开发人员可以做到“易者易为”。
关于部署,现在的一个方向是部署的自动化,有很多工具可以支持我们做到这一点,比如 Chef、Puppet,我最近的一个项目上用了 Docker。有了这些基础,我们可以一键式在一台空机器上建立起一个完整的应用。这就是持续交付中一个很重要的基础。再进一步,我们可以把这种部署同虚拟化和云结合起来,用自动化工具在云端一个节点部署出我们的应用。你可以想一下,如果我需要测试一下我的应用,或是在产品环境上增加一个新节点,我只要用一条命令,就会自动在云端的某个节点上建出我们所需的全部内容。传统做法仅仅是申请机器就是一个漫长的过程,遑论手工安装应用,配置参数这些麻烦事。这不是对未来美好生活的畅想,实际上,我们公司的许多项目已经做到了这一点。
把部署自动化和轻量级部署、微服务结合起来,我们的开发方式就是,在本地编写好一个服务,调测好,再部署到云端,由其它人进一步测试。这才是一种简单的开发方式。程序员应该追求简单,包括我们个人开发方式的简单。
感谢杨赛对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。
评论