2000年后,在迷茫中摸索的Java終于找到了屬于自己的爆發(fā)點(diǎn)——企業(yè)級(jí)開(kāi)發(fā)。許多方式方法,也在那時(shí)逐漸成型。我們不妨回顧那是的Java開(kāi)發(fā)是怎樣的面貌。 1.Java1.4已經(jīng)發(fā)布,不過(guò)大多數(shù)人還用著Java1.3。 2.Ant是主流構(gòu)架工具,Maven還是新東西。 3.J2EE是主流,幾乎所有的“現(xiàn)代”Java應(yīng)用必須用到EJB 2 4.。Gavin King發(fā)布了Hibernate,將ORM正式引入到Java世界,但許多程序員還在直接使用JDBC。 5.Rod Johnson寫(xiě)作了《Expert One-no-One J2EE Design and Development》,其中介紹了一個(gè)框架,后來(lái)稱(chēng)為spring Framework。再后來(lái),Rod Johnson用一本《J2EE Development without EJB》,向人們展示了J2EE有多么的笨拙。 6.作為一個(gè)Web開(kāi)發(fā)框架,Struts正逐漸替代Servlet稱(chēng)為主流。 7.如果你是Java程序員,就不難發(fā)現(xiàn),如今廣為人知的許多技術(shù),例如Maven、 Spring Framework、Hibernate、Struts,當(dāng)時(shí)就已成為開(kāi)發(fā)者常用工具。 遺憾的是,這些十多年前就已定型的工具和開(kāi)發(fā)方式,時(shí)至今日依然是許多Java程序員的首選。我們不是說(shuō),軟件技術(shù)更新得快嗎?
十年間 【開(kāi)源成為主流】 當(dāng)年,Eric Raymond寫(xiě)下《大教堂與集市》,努力為開(kāi)源運(yùn)動(dòng)爭(zhēng)取正統(tǒng)地位。而今,開(kāi)源早已成為廣為接受的正統(tǒng)同理念,連當(dāng)年許貌似迂腐不堪的的大眾司都對(duì)開(kāi)源張開(kāi)了懷抱。今天的開(kāi)源已成為新技術(shù)、新發(fā)展方向的代名詞,“老大哥”主導(dǎo)軟件開(kāi)發(fā)方向的年代已然一去不復(fù)返了。關(guān)于Java當(dāng)年Rod Johnson發(fā)起了Without EJB大戰(zhàn),大公司的權(quán)威轟然倒塌,以spring Framework、Hibernate等為代表的開(kāi)源軟件正式成為Java世界的主角。 【敏捷/精益開(kāi)發(fā)成為日用品】 不管你是否認(rèn)同,敏捷/精益開(kāi)發(fā)直接影響了整個(gè)行業(yè),對(duì)程序員最直接的影響是“測(cè)試”,它不再是可有可無(wú)了。優(yōu)秀的程序員可以深刻理解測(cè)試能有效驅(qū)動(dòng)設(shè)計(jì)。優(yōu)秀的團(tuán)隊(duì)開(kāi)始使用BDD、SBE等技術(shù),從業(yè)務(wù)層面對(duì)系統(tǒng)進(jìn)行測(cè)試。隨之而來(lái)的是持續(xù)集成變?yōu)槊總€(gè)團(tuán)隊(duì)的標(biāo)配,更有追求的團(tuán)隊(duì)已奔著持續(xù)交付前進(jìn)。而這一切理念的背后的支撐幾乎都來(lái)自Java世界,無(wú)論是JUnit是Jez Humble在使用Java寫(xiě)就的就是軟件中總結(jié)出來(lái)的。 【Ruby on Rails帶來(lái)開(kāi)發(fā)思路的轉(zhuǎn)變】 在一篇關(guān)于Java的文章中出現(xiàn)Ruby顯得有些突兀,但Rails問(wèn)世之初,真是震撼了整個(gè)軟件行業(yè)。其中諸多理念產(chǎn)生了深刻影響,例如約定優(yōu)于配置、DSL、輕量級(jí)部署、自動(dòng)化等,且不說(shuō)有多少模仿Rails的框架誕生,單看后來(lái)出現(xiàn)的Java框架在表達(dá)性上所下的功夫,就能夠略知一二。 【多核帶動(dòng)函數(shù)式編程興起】 【互聯(lián)網(wǎng)讓資源豐富】 2000年之后,互聯(lián)網(wǎng)泡沫雖然破滅,但不妨礙互聯(lián)網(wǎng)技術(shù)的飛速發(fā)展,它逐漸成為人們?nèi)粘I钪兄匾囊徊糠?。我們能第一時(shí)間與世界最新技術(shù)接軌,與高手過(guò)招。借助開(kāi)源技術(shù)興起的互聯(lián)網(wǎng)公司又用云、大數(shù)據(jù)等基礎(chǔ)設(shè)施回饋產(chǎn)業(yè),進(jìn)一步降低了互聯(lián)網(wǎng)的準(zhǔn)入門(mén)檻。Java的部署方式從此巨變,唾手可得的運(yùn)資源讓部署不再是一件難事,名噪一時(shí)的應(yīng)用服務(wù)器似乎也到了蛻變的邊緣。 【程序設(shè)計(jì)語(yǔ)言不斷發(fā)展】 《The Pragmatic Programer》曾建議程序員每年學(xué)習(xí)一門(mén)新語(yǔ)言。最近十年是程序設(shè)計(jì)語(yǔ)言蓬勃發(fā)展的十年,僅在我們熟悉的JVM上,就有多種新型語(yǔ)言誕生,如Groovy、Scala、JavaScript這樣的流行語(yǔ)言移植到了JVM,它以逐漸成為平臺(tái)。即便是Java語(yǔ)言自身,從5到8,也有了天翻地覆的變化,只不過(guò),現(xiàn)在許多人學(xué)到的Java還是最原始的版本,語(yǔ)言自身的表達(dá)能了都未能完全發(fā)揮。
十年后 即便是把鈍刀,從新磨礪,依然可以披荊斬棘。如果把十年間的運(yùn)用回Java,他可以熠熠生輝。 【整潔代碼與DSL】 傻瓜都能寫(xiě)出技術(shù)機(jī)可以理解的代碼,優(yōu)秀的程序員要編寫(xiě)人能理解的代碼。 這是Martin Fowler 1999年在《重構(gòu)》中寫(xiě)下的第一句話,遺憾的是,還有許多團(tuán)隊(duì)每天努力加班寫(xiě)面條一樣的長(zhǎng)的代碼。Kent Beck告訴我們什么代碼是好代碼——Clean Code with Test。至于什么是Clean Code,Robert Martin寫(xiě)了整整一本書(shū)——《Clean Code》。但對(duì)于眼中只有功能代碼的程序員,無(wú)法理解可讀性的重要性,自然也就無(wú)法理解新近這些貌似等價(jià)的更新,只能繼續(xù)在焦油坑中掙扎。 我將DSL視為整潔代碼的自然擴(kuò)展,代碼不僅要可讀,更要最求良好的表達(dá)性。對(duì)于Java程序員,有兩層含義:一是選擇程序庫(kù)的重要表準(zhǔn),功能相近者,有良好DSL者勝;二是我應(yīng)該深入了解語(yǔ)言的特性,有能力打造只記得DSL,讓程序更整潔。 對(duì)于整潔的代碼不斷最求,恰是后文幾項(xiàng)值得我們深入探索的根基。 【Java“新”語(yǔ)言】 Java?。蛋凑f(shuō)都已經(jīng)過(guò)時(shí)了,不少的程序員卻還是不能充分利用語(yǔ)言的特性簡(jiǎn)化代碼,例如以下方面: 1.泛型不僅適用在容器上,還可以把很多Object踢開(kāi); 2.Annotation,許多人只是拿來(lái)用,卻從未考慮構(gòu)建自己的annotation簡(jiǎn)化代碼; 3.Static import可以讓我們寫(xiě)出漂亮易讀的代碼; 4.利用參變,API可以很靈活。 如今Java 8已經(jīng)問(wèn)世,有了lambda、default?。恚澹簦瑁铮?,代碼可以進(jìn)一步簡(jiǎn)化,只不過(guò),要走的路還很長(zhǎng)。 【函數(shù)式編程】 之所以應(yīng)該學(xué)習(xí)新語(yǔ)言,更多的是為了學(xué)習(xí)新思想,而不僅是語(yǔ)法。對(duì)于許多Java程序員來(lái)說(shuō),函數(shù)式編程時(shí)新思想,雖然它已經(jīng)存在幾十年了。函數(shù)式編程的好處有下面一些。 1.函數(shù)組合可以降低代碼解耦。 2.列表轉(zhuǎn)換思維方式可以消除大多數(shù)for。 3.不變性讓軟件更穩(wěn)定。 4.惰性求職可以減少資源耗費(fèi)。
函數(shù)式編程有多重要,看看Java8加入Lambda便可略知一二。縱然只運(yùn)用老版本,我們依然可以借助如Guava這樣的程序庫(kù)相關(guān)功能。當(dāng)然,如何從分發(fā)揮函數(shù)式的威力,尤其是在Java世界里,還有待進(jìn)一步發(fā)掘。 【新風(fēng)格程序庫(kù)】 所謂新風(fēng)格,不是新功能,而是那些符合現(xiàn)代程序設(shè)計(jì)風(fēng)格的程序庫(kù)。在我看來(lái),除了基本功能,一個(gè)很重要的標(biāo)準(zhǔn)是,擁有設(shè)計(jì)良好的API,按前面的標(biāo)準(zhǔn),大多擁有良好的DSL。 下面列舉了幾個(gè)符合這種風(fēng)格標(biāo)準(zhǔn)的程序庫(kù),幾種是開(kāi)箱即用,也是讀者從本文獲得的最直接的收獲。 1.首先是Guava,只要你做Java項(xiàng)目,就應(yīng)該用Guava。它在某種程度上彌補(bǔ)了JDK的不足。舉個(gè)簡(jiǎn)單的例子,將文件寫(xiě)入字符串,如果用JDK實(shí)現(xiàn),光想著異常處理都會(huì)讓人頭疼不已。Guava是一個(gè)現(xiàn)代程序庫(kù),有著更易用的API,還有集合類(lèi)、緩存等新功能。Guava做得怎么樣?看看Java?。傅奈臋n就能知道,一些API幾乎原封不動(dòng)地從Guava上借鑒而來(lái)。 2.如果把JDK的抄襲作為一種贊揚(yáng),除了Guava,另一個(gè)值得贊揚(yáng)的程序庫(kù)就是Joda?。裕椋恚?。正如每個(gè)Java程序員都知道的,JDK原有的日期數(shù)據(jù)庫(kù)設(shè)計(jì)非常糟糕,Joda?。裕椋恚逭菫榱吮荛_(kāi)這個(gè)問(wèn)題。因?yàn)樗O(shè)計(jì)得好,所以才有了JSR?。常保啊F(xiàn)已成為Java8的一部分。不過(guò),從發(fā)展來(lái)看,距離Java8廣泛使用還有很長(zhǎng)的路要走。大多數(shù)人還會(huì)繼續(xù)與Java6作斗爭(zhēng)。 3.Hamcrest和Mockito,是兩個(gè)測(cè)試庫(kù)。Hamcrest讓我們更好地寫(xiě)斷言,而Mockito則能更好地寫(xiě)Mock對(duì)象,它們脫穎而出完全是因其良好的API設(shè)計(jì)。 4.DropWizard可理解成一個(gè)開(kāi)發(fā)REST服務(wù)的框架,但其實(shí)它什么都沒(méi)做,只是將自己已有框架集成。它同前面幾個(gè)程序庫(kù)有很大的不同,更多地代表了一種開(kāi)放式——輕量級(jí)部署風(fēng)格,拋開(kāi)沉重的應(yīng)用服務(wù)器。它未必是未來(lái)的贏家,但值得了解。 其實(shí),還有一些不錯(cuò)的程序庫(kù)值得推薦,比如,實(shí)現(xiàn)Actor的Akka,實(shí)現(xiàn)相應(yīng)是編程的RxJava,這些庫(kù)往往代表了特定的程序設(shè)計(jì)風(fēng)格。 【測(cè)試、測(cè)試、測(cè)試】 必須強(qiáng)調(diào)一點(diǎn),測(cè)試是每個(gè)開(kāi)發(fā)者必須做的事。自動(dòng)化測(cè)試并費(fèi)僅靠一個(gè)框架就能完成,想讓測(cè)試成為開(kāi)發(fā)的幫手,還需要從多個(gè)方面耐心打磨。開(kāi)發(fā)團(tuán)隊(duì)容易忽略的方面是,構(gòu)建開(kāi)發(fā)者與其他角色連接的測(cè)試,這類(lèi)測(cè)試有許多名字:驗(yàn)收測(cè)試、BDD、Specification by Example,重點(diǎn)在于,這是開(kāi)發(fā)人員的工作,要讓其他角色易于理解。如果你認(rèn)為Java測(cè)試就是JUnit,只能說(shuō)明一點(diǎn),你落伍太多了。且不說(shuō)前文已經(jīng)提到的Hamcrest和Mockito能讓測(cè)試質(zhì)量得到大幅度提升,但說(shuō)JUnit只是一個(gè)單元測(cè)試框架,用它做其他類(lèi)型測(cè)試簡(jiǎn)直如同用匯編開(kāi)發(fā)Web應(yīng)用。對(duì)于業(yè)務(wù)層面的測(cè)試,Cucumber是很不錯(cuò)的選擇,不過(guò),其缺省版本使用Ruby實(shí)現(xiàn)的。對(duì)于執(zhí)著的Java程序員,Cucumber其實(shí)也有Java版本。如果你非要嘗試更純粹的Java,Concordion是另外一個(gè)選擇,用他寫(xiě)完的測(cè)試,完全可以成為一個(gè)漂亮的網(wǎng)站。 【自動(dòng)化】 自動(dòng)化對(duì)每個(gè)項(xiàng)目來(lái)說(shuō)都是必不可少,不僅包括編譯和運(yùn)行測(cè)試,還包括開(kāi)發(fā)過(guò)程的幾乎每個(gè)方面。一個(gè)簡(jiǎn)單的例子是,開(kāi)發(fā)者應(yīng)該自動(dòng)化生成IDE工程,而不需要手動(dòng)配置了。具體到Java領(lǐng)域,首先是工具的變化,請(qǐng)告別Ant和Maven,開(kāi)始使用Gradle或Buildr。使用完整程序設(shè)計(jì)語(yǔ)言支撐的構(gòu)建工具,才能真正做到將開(kāi)發(fā)的方方面面自動(dòng)化,因?yàn)閳F(tuán)隊(duì)的特殊需求,只能靠自己編碼實(shí)現(xiàn)。 【輕量級(jí)部署】 這是一種擺脫“老大哥”的趨勢(shì)。在許多Java程序員的概念中,部署一定要有專(zhuān)門(mén)的應(yīng)用服務(wù)器,這邊是當(dāng)年的“老大哥”圈套。所謂輕量級(jí),站在開(kāi)發(fā)角度來(lái)看,部署不一定要專(zhuān)門(mén)的服務(wù)器,現(xiàn)在一種趨勢(shì)是采用嵌入服務(wù)器,完全可以做成獨(dú)立應(yīng)用。對(duì)于程序員來(lái)說(shuō),意味著我們有機(jī)會(huì)在IDE調(diào)試服務(wù),而不再殺雞用牛刀地每每動(dòng)用“遠(yuǎn)程調(diào)試”大招。輕量級(jí)部署可以自然延展到Devops,本著“基礎(chǔ)設(shè)施作為代碼”的理念,將部署完全自動(dòng)化。再進(jìn)一步,如果云結(jié)合,意味著隨時(shí)隨地可以創(chuàng)建應(yīng)用服務(wù)。有了這樣的輕量級(jí)部署,再加上為服務(wù)的理念,就可按需拓展服務(wù),更好地實(shí)現(xiàn)自動(dòng)化運(yùn)維。 【Java.NEXT】 Java.NEXT,通常意味著我們可使用不同程序設(shè)計(jì)語(yǔ)言,讓Java開(kāi)發(fā)進(jìn)入另一個(gè)層面。JVM上各種語(yǔ)言蓬勃發(fā)展,徹底打破了Java最初“一種語(yǔ)言,多個(gè)平臺(tái)”的理念。但習(xí)慣的力量是強(qiáng)大的,對(duì)于習(xí)慣了Java開(kāi)發(fā)的企業(yè)來(lái)說(shuō),即便同在JVM平臺(tái),完全使用新語(yǔ)言也幾乎無(wú)法實(shí)現(xiàn)。但我們可以采取逐步滲透的方式,在不同的場(chǎng)景下,選擇不同語(yǔ)言,先行嘗試。例如選擇Gradle的團(tuán)隊(duì)實(shí)際上已經(jīng)在用Groovy做構(gòu)建腳本,也可以使用Scala做單元測(cè)試。 【遺留系統(tǒng)】
|
|