輕量級(jí)開(kāi)發(fā)是一個(gè)很大的主題,開(kāi)發(fā)人員經(jīng)常提到這個(gè)術(shù)語(yǔ),但卻很難講明它的意思。本文是一系列講述輕量級(jí)開(kāi)發(fā)的文章中的首篇,介紹了該技術(shù)背后的核心原則及原理。
1990 年,我發(fā)現(xiàn)了白水漂流并深深愛(ài)上了它。我們哪怕是經(jīng)過(guò)最小的湍流,都會(huì)留一個(gè)人在湍流尾部,兩個(gè)人在岸邊用繩索拽著。我們認(rèn)為這可以防止任何糟糕的事情發(fā)生。雖然看起來(lái)一切盡在掌握,只是有些不太實(shí)際。我們還學(xué)會(huì)了從船艙觀察普通的湍流,并設(shè)法互相協(xié)作。對(duì)于大多數(shù)危險(xiǎn)的湍流,我們花費(fèi)了更多的時(shí)間來(lái)保障安全,但是只有少數(shù)情況下,這些措施才起到重大的作用。
在漂流過(guò)程中,使用一種起源于東南部湍急河流的輕量級(jí)策略,為我節(jié)省了時(shí)間,使我可以劃得更遠(yuǎn),玩得更開(kāi)心,而無(wú)需過(guò)多考慮安全問(wèn)題。在業(yè)務(wù)領(lǐng)域,輕量級(jí)開(kāi)發(fā)讓您可以按時(shí)完工,積極響應(yīng)客戶,從而節(jié)省時(shí)間和金錢。
在本系列的文章中,我關(guān)注于輕量級(jí)開(kāi)發(fā)(曾經(jīng)有太多含義的術(shù)語(yǔ))的基礎(chǔ)。本篇文章作為第一篇,為讀者打好基礎(chǔ),同時(shí)對(duì)輕量級(jí)開(kāi)發(fā)做出定義。后面的文章由淺入深地講述從過(guò)程到原則最后到工具的知識(shí)。我也將在更高的級(jí)別上關(guān)注原理和架構(gòu)的實(shí)現(xiàn),并且提供具體實(shí)現(xiàn)的代碼。
本系列面向沒(méi)有經(jīng)過(guò)太多輕量級(jí)開(kāi)發(fā)的讀者。如果您已使用了兩年的 Spring 輕量級(jí)容器和敏捷過(guò)程,您可能會(huì)收獲更多。如果您在傳統(tǒng)的開(kāi)發(fā)過(guò)程中使用 Enterprise JavaBeans?(EJB),但想要轉(zhuǎn)向輕量級(jí)開(kāi)發(fā),那么本系列就是為您準(zhǔn)備的。
我更多地是想在這場(chǎng)席卷整個(gè) Java? 技術(shù)社區(qū)的潮流中,做一些自己的貢獻(xiàn)。輕量級(jí) 這個(gè)噱頭為諸如 Spring 和 Pico 這樣的容器增添了幾分優(yōu)雅。并且,一些源自輕量級(jí)過(guò)程的技術(shù),如自動(dòng)化單元測(cè)試,現(xiàn)在也滲透到了很多開(kāi)發(fā)工作室中。
戳穿針對(duì)輕量級(jí)開(kāi)發(fā)的謠言
“輕量級(jí)開(kāi)發(fā)”通常與一套開(kāi)發(fā)方法、框架和設(shè)計(jì)原理一起使用。
- 輕量級(jí)方法 包括敏捷過(guò)程,例如極限編程(XP)和 Scrum。它們強(qiáng)調(diào)開(kāi)發(fā)中測(cè)試第一,積極調(diào)動(dòng)客戶和重構(gòu)。
- 輕量級(jí)框架 鼓勵(lì)人們使用簡(jiǎn)單原始的 Java 對(duì)象(POJO)編程,而不是類似 EJB 的重量級(jí)面向組件模型。
- 輕量級(jí)設(shè)計(jì)模式 使您可以在對(duì)象和集成服務(wù)之間進(jìn)行松散耦合,而無(wú)需艱苦地編寫業(yè)務(wù)邏輯或領(lǐng)域模型。
當(dāng)我們研究這些思想和技術(shù)時(shí),您將會(huì)學(xué)到更多關(guān)于它們的知識(shí)。但是首先讓我們戳穿一些謠言。
謠言:輕量級(jí)開(kāi)發(fā)只是一種“玩具”技術(shù)。
許多開(kāi)發(fā)工具,如 Microsoft? Visual Basic 或 PHP,它們通常不能駕馭或管理大型企業(yè)項(xiàng)目,因此得到了“玩具”的稱號(hào)。像 Spring 和 Hebernate 這樣的輕量級(jí)技術(shù)就常常因此而黯淡。實(shí)際上,大多數(shù)輕量級(jí)技術(shù)用于了企業(yè)開(kāi)發(fā),因?yàn)槠渌夹g(shù)都使我們非常失望。Spring 框架就是作為代替 EJB 的一種輕量級(jí)技術(shù)。同樣,XP 方法吸收改進(jìn)了企業(yè)中的錯(cuò)誤設(shè)置。我在獲得 Jolt 大獎(jiǎng)的 Better, Faster, Lighter Java 一書(shū)中,為大家講述了有關(guān)成功部署在我的客戶站點(diǎn)上的一些工具的信息,客戶有一些是財(cái)富 500 強(qiáng)中的公司。輕量級(jí)技術(shù)在企業(yè)領(lǐng)域內(nèi),正在蓬勃發(fā)展著。
謠言:輕量級(jí)開(kāi)發(fā)策略構(gòu)建的是“玩具”。
也許您更傾向于相信輕量級(jí)開(kāi)發(fā)只對(duì)構(gòu)建“玩具”應(yīng)用程序有益。而您的目標(biāo)是精確地滿足客戶的需求。讓我們首先明確一下:輕量級(jí)技術(shù)完全可以構(gòu)建這種規(guī)模的應(yīng)用程序。實(shí)際上,這種巨大的反差經(jīng)常發(fā)生,因?yàn)橹挥泻?jiǎn)單、簡(jiǎn)潔、無(wú)狀態(tài)的設(shè)計(jì)才能使基礎(chǔ)設(shè)施更好地工作。
謠言:輕量級(jí)過(guò)程使您忽視規(guī)范。
在輕量級(jí)開(kāi)發(fā)中,您需要認(rèn)真地規(guī)劃并與客戶磋商需求。您必須構(gòu)建嚴(yán)格的自動(dòng)化單元測(cè)試,以優(yōu)化重構(gòu)。當(dāng)放棄變更時(shí),仍可以保持程序完整。而且,測(cè)試用例失敗或變更引發(fā)錯(cuò)誤時(shí),自動(dòng)化構(gòu)建會(huì)通知您。輕量級(jí)開(kāi)發(fā)必須比其他技術(shù)更加注意規(guī)范,但這種規(guī)范源于不同方面。
我認(rèn)為這種開(kāi)發(fā)風(fēng)格超越了單一的技術(shù)或過(guò)程。如果您想輕松一些,那么需要選擇使它易于工作的原則、過(guò)程和技術(shù)。
原則
該說(shuō)的也說(shuō)了,該做的也做了,您現(xiàn)在需要決定哪些需要重視,并據(jù)此制定決策。如果我覺(jué)得客戶被誤導(dǎo)或漠不關(guān)心,我通常會(huì)首先幫助他們建立核心原則。下面的列表是一個(gè)不錯(cuò)的起點(diǎn):
- 爭(zhēng)取簡(jiǎn)單性。這種觀念應(yīng)該滲入到您所有的工作中。您的過(guò)程應(yīng)該剛好生成足夠完成工作的工件。開(kāi)發(fā)人員應(yīng)該盡量使用最簡(jiǎn)單的方法解決問(wèn)題。您的工具應(yīng)該使您構(gòu)建一個(gè)清晰、簡(jiǎn)潔的解決方案。
- 修補(bǔ)漏洞。許多開(kāi)發(fā)方法可能不鼓勵(lì)在過(guò)程中進(jìn)行重構(gòu)或變更,因?yàn)檫@些行為不直接用于產(chǎn)生客戶代碼。輕量級(jí)開(kāi)發(fā)要求可以自由地修補(bǔ)太復(fù)雜或充斥 bug 的代碼。您需要為它做出預(yù)算。
- 自動(dòng)化單元測(cè)試。您應(yīng)該優(yōu)先編寫測(cè)試用例。您可能還沒(méi)有在測(cè)試第一的開(kāi)發(fā)中成功過(guò),但測(cè)試會(huì)間接給您帶來(lái)重構(gòu)代碼的便利。我以后會(huì)進(jìn)一步講述:廣泛的單元測(cè)試改善您的客戶體驗(yàn),并提高代碼的設(shè)計(jì)水平,這是因?yàn)樗鼜?qiáng)迫您解耦聯(lián)系過(guò)于緊密的代碼。
- 使用短開(kāi)發(fā)周期并積極調(diào)動(dòng)客戶參與其中。許多頂級(jí)的軟件工作室通過(guò)剔除不必要的工件來(lái)簡(jiǎn)化開(kāi)發(fā)周期。如果您已經(jīng)順利得到客戶的參與,那么很多的功能規(guī)范會(huì)變得越來(lái)越?jīng)]必要。客戶會(huì)很滿意這種交互,并感激您的短周期開(kāi)發(fā),因?yàn)檫@穩(wěn)步提高了客戶的業(yè)務(wù)價(jià)值。
這些原則并不能完全包含您的技術(shù)抉擇和開(kāi)發(fā)過(guò)程,但它有利于您描述開(kāi)發(fā)體驗(yàn)。如果經(jīng)理也了解并遵循這些原則,開(kāi)發(fā)人員就不至于做出無(wú)效技術(shù)選擇,或者開(kāi)發(fā)一些不必要的工件。確立原則后,就該規(guī)劃一個(gè)有效過(guò)程了。
過(guò)程
緊湊、快速的開(kāi)發(fā)過(guò)程通常從敏捷開(kāi)發(fā)方法 當(dāng)中得到靈感。然而,這些方法并不針對(duì)每個(gè)人。如果您有一個(gè)大型團(tuán)隊(duì),并且沒(méi)有實(shí)際訪問(wèn)客戶或合適的代理人,那么傳統(tǒng)方法更適合您一些。但多數(shù)項(xiàng)目都有小團(tuán)隊(duì) —— 不超過(guò) 12 個(gè)人,他們可以充分訪問(wèn)客戶,以靈活使用這種方法。通常,敏捷開(kāi)發(fā)包括下列原則:
- 專注現(xiàn)場(chǎng)客戶和代碼,而不是其他設(shè)計(jì)技巧。您可以使用其他技巧,但只在它們對(duì)您確實(shí)有益的情況下。本過(guò)程不需要它。
- 簡(jiǎn)化您需要的文檔。為了需要,寧可使用電子表格中的一行來(lái)描述,也不使用令人困惑的用例圖。
- 只做足以完成工作的設(shè)計(jì)工作。不要對(duì)設(shè)計(jì)或性能過(guò)分憂心忡忡,使自己陷入絕境。
- 為了開(kāi)發(fā),努力進(jìn)行簡(jiǎn)化并保證至少每天都集成您所構(gòu)建的程序,必要時(shí)進(jìn)行重構(gòu)。
- 自動(dòng)化測(cè)試。
即使您工作在傳統(tǒng)的機(jī)構(gòu),您也可以利用已裁減的開(kāi)發(fā)過(guò)程。技巧是推廣原則 而不是方法。推廣極限編程管理器 —— 或其他冠以極限 的東西,這可能會(huì)很艱難。但推廣類似單元測(cè)試的原則通常更有意義。實(shí)際上,我的許多客戶使用這種技術(shù)同敏捷開(kāi)發(fā)過(guò)程一起為保守的機(jī)構(gòu)服務(wù),但他們的老板絲毫不知道有什么發(fā)生了改變。
用修辭手法描述一下這種技術(shù)。原則 是重拳出擊的輕量級(jí)思想。過(guò)程是重量級(jí)的,實(shí)現(xiàn)起來(lái)將會(huì)很困難。
技術(shù)
我已經(jīng)概述了大多數(shù)輕量級(jí)開(kāi)發(fā)人員需要了解的設(shè)計(jì)原理,以及利用這些原理的重要開(kāi)源技術(shù)。
依賴注入
最新一代容器稱為輕量級(jí)容器,它們使用一個(gè)共同設(shè)計(jì)原理:依賴注入。 對(duì)這個(gè)簡(jiǎn)單思想來(lái)說(shuō),這是一個(gè)復(fù)雜的術(shù)語(yǔ)。依賴注入讓您將對(duì)象和它所依賴的東西交給第三方。然后第三方創(chuàng)建所有對(duì)象并將它們綁在一起。比方說(shuō),稱為 myDao
的數(shù)據(jù)訪問(wèn)對(duì)象需要一個(gè)稱為 ds
的數(shù)據(jù)源。那么該容器會(huì)一同創(chuàng)建它們,并設(shè)置一個(gè)屬性:
|
當(dāng)然,不創(chuàng)建這種第三方匯編程序的話,您也可以使用框架來(lái)做其他附加的工作(如提供配置支持)。Spring 框架、Pico 和 HiveMind 就扮演了這個(gè)角色。其他像 JavaServer Faces(JSF) 框架也利用了依賴注入。
面向?qū)ο缶幊?/SPAN>
使用面向?qū)ο缶幊蹋ˋOP),您可以編寫通用的功能性模塊(稱為方面) —— 例如,日志、事務(wù)、安全或持久性。AOP 使您可以將這些方面聯(lián)系到 POJO,然后指定一個(gè)時(shí)間點(diǎn)(如方法開(kāi)始時(shí)或產(chǎn)生異常時(shí))和另一個(gè)需要聯(lián)系的方面。例如,您可能想要?jiǎng)?chuàng)建一個(gè)外觀事務(wù)對(duì)象。您可以在調(diào)用方法時(shí)將 TransactionBegin
方面關(guān)聯(lián)到外觀方法。然后在產(chǎn)生異常時(shí)將 RollBack
方面關(guān)聯(lián)到外觀的異常。最后,在方法結(jié)束時(shí)將 Commit
方面關(guān)聯(lián)到外觀的方法。您在配置中完成這些工作,而不是通過(guò)編寫代碼。依靠這種能力,您可以創(chuàng)建一個(gè)簡(jiǎn)單的 POJO 事務(wù)、安全或遠(yuǎn)程訪問(wèn)。
您現(xiàn)在已經(jīng)得到了關(guān)于 POJO 的聲明性事務(wù),這對(duì)企業(yè)應(yīng)用程序非常有用。使用這些工具,您可以完全放棄 EJB,或者最小化它的作用。而這正是輕量級(jí)組件所要做的。
透明持久性
持久性也是建立在較簡(jiǎn)單的編程模型之上。透明持久性框架通過(guò)配置而不是編寫代碼,來(lái)使您為應(yīng)用程序添加持久性。因?yàn)榇蠖鄶?shù)應(yīng)用程序是面向?qū)ο蟮模⑶以L問(wèn)一個(gè)關(guān)系數(shù)據(jù)庫(kù),所以一些專家斷言,我們最終將進(jìn)入對(duì)象關(guān)系映射的時(shí)代。我目前發(fā)現(xiàn)的頂級(jí)持久性解決方案是 SolarMetric 的 Kodo JDO 和 Hibernate(參閱 參考資料)。在后面的文章中我將詳細(xì)比較這些解決方案。其他輕量級(jí)解決方案,例如 iBATIS 和 Active Record 設(shè)計(jì)模式,根本不會(huì)試圖進(jìn)行對(duì)象關(guān)系映射。
結(jié)束語(yǔ)
在輕量級(jí)開(kāi)發(fā)中,您基本上可以:
- 合并過(guò)程、技術(shù)和原理。
- 優(yōu)先選擇較簡(jiǎn)單的技術(shù)。
- 在一個(gè)穩(wěn)固、輕量級(jí)的基礎(chǔ)上,進(jìn)行構(gòu)建。
- 盡量爭(zhēng)取最可能的透明性。
- 使用您可以利用的技術(shù),如依賴注入和 AOP。
一定要明白,無(wú)論技術(shù)還是過(guò)程都不能完整定義輕量級(jí)開(kāi)發(fā)。它是一個(gè)包羅萬(wàn)象的概念。伴隨本系列的文章,您將看到對(duì)輕量級(jí)技術(shù)和原理的各種各樣的討論。我將首先關(guān)注開(kāi)源框架,并著重講述輕量級(jí)容器。后面的文章,我會(huì)討論保守公司內(nèi)的輕量級(jí)方法實(shí)現(xiàn),甚至還有一些超越了 Java 技術(shù)的替代方案。我非常喜歡這個(gè)系列的文章,希望您也一樣。