9、 可撤銷性前端
有許多人會設法保持代碼的靈活性,而你還須要考慮維持架構、部署及供應商集成等領域的靈活性。算法
一般你能夠把第三方產品隱藏在定義良好的抽象接口後面。事實上,在咱們作過的任何項目中,咱們都總可以這麼作。但假定你沒法那麼完全地隔離它,若是你必須大量地把某些語句分散在整個代碼中,該怎麼辦?把需求放入元數據,而且使用某種自動機制——好比Aspect或Perl——把必要的語句插入代碼自身中。不管你使用的是何種機制,讓它可撤銷。若是某樣東西是自動添加的,他就能夠被自動去掉。數據庫
10、曳光彈前端框架
在黑暗中用機槍射擊能夠用曳光彈的方式。曳光彈與常規彈藥交錯着裝在彈藥帶上。發射時,曳光彈中的磷點燃,在槍與它們擊中的地方之間留下一條煙火般的蹤影。若是曳光彈擊中目標,那麼常規子彈也會擊中目標。服務器
這個類比也許有些暴力,蛋它適用於新的項目,特別是你構建從未構建過的東西時。與槍手同樣,你也設法在黑暗中擊中目標。由於你的用戶從未見過這樣的系統,他們的需求可能會含糊不清。由於你在使用不熟悉的算法、技術、語言和庫,你面對着大量未知的事物。同時,由於完成項目須要時間,在很大程度上你可以通知,你的工做環境將在你完成以前發生變化。架構
在黑暗中發光的代碼框架
曳光彈行之有效,是由於它們與真正的子彈在相同的環境、相同的約束下工做。它們快速飛向目標,因此搶手能夠獲得即時的反饋。同時,從實踐的角度看,這樣的解決方案也更便宜。工具
爲了在代碼中得到一樣的效果,咱們要找到某種東西,讓咱們能快速、直觀和可重複地從需求出發,知足最終系統的某個方面要求。佈局
有一次,咱們接受了一個複雜的客戶-服務器數據庫營銷項目。其部分需求是要可以指定並執行臨時查詢。服務器是一系列專用的關係數據庫。用Object Pascal編寫的客戶GUI使用一組C庫提供給服務器的接口。在轉換爲優化的SQL以前,用戶的查詢以相似Lisp的表示方式存儲在服務器上;轉換直到執行前才進行。有許多未知因素和許多不一樣的環境,沒有人清楚地直到GUI應該怎樣工做。性能
這是使用曳光代碼的好機會。咱們開發了前端框架、用於查詢的庫以及用於把所存儲的查詢轉換爲具體數據庫的查詢的結構。隨後咱們把它們幾種在一塊兒,並檢查它們是否能工做。使用最初構建的系統,咱們所能作的只是提交一個查詢,列出某個列表中的全部行,但它證實了UI可以與庫交談,庫可以對查詢進行序列化和解序列化,而服務器可以根據結果生成SQL。在接下啦的幾個月裏,咱們逐漸充實這個基本結構,經過並行地擴大曳光代碼的各個組件增長新的功能。當UI增長了新的查詢類型時,庫隨之成長,而咱們也使SQL生成變得更爲成熟。
曳光代碼並不是用過就扔的代碼:你編寫它,是爲了保留它。它含有任何一段代碼產品都擁有的完整的錯誤檢查、結構、文檔、以及自查。它只不過功能不全而已。可是,一旦你在系統的各組件間實現了端到端的鏈接,你就能夠檢查你離目標還有多遠,並在必要的狀況下進行調整。一旦你徹底瞄準,增長功能將是一件容易的事。
曳光開發與項目永不會結束的理念是一致的:總有改動須要完成,總有功能須要增長。這是一個漸進的過程。
另外一種傳統方法是一種繁重的工程方法:把代碼劃分爲模塊,在真空中對模塊進行編碼,把模塊組合成子配件,再對自配件進行組合,直到有一天你擁有完整的應用爲止。直到那時,才能把應用做爲一個總體呈現給用戶,並進行測試。
曳光代碼方法有許多優勢:
曳光彈並不是總能命中目標
曳光彈告訴你擊中的是什麼。那不必定老是目標。因而你調整準星,直到徹底擊中目標爲止。這正是要點所在。
曳光代碼也是如此。你在不能100%肯定該去往何處的情形下使用這項技術。若是最初的幾回嘗試錯過了目標——用戶說:「那不是個人意思」,你須要的數據在你須要它時不可用,或是性能好像有問題——你不該感到驚奇。找出怎樣改變已有的東西、讓其更接近於目標的辦法,而且爲你使用了一種簡約的開發方法而感到高興。小段代碼的慣性也小——要改變它更容易、更迅速。你可以蒐集關於你應用的反饋,並且與其餘任何方法相比,你可以話費較小的代價、更爲迅速地生成新的、更爲準確的版本。同時,由於每一個主要的應用組件都已表如今你的曳光代碼中,用戶能夠確信,他們所看到的東西具備現實基礎,不只僅是紙上的規範。
曳光代碼 vs 原型製做
你也許會想,這種曳光代碼的概念就是原型製做,只不過有一個更富「進攻性」的名字。他們有所區別。使用原型,你是要探究最終系統的某些的方面。使用真正的原型,在對概念進行了實驗以後,你會把你捆紮在一塊兒的不管什麼東西扔掉,並根據你學到的經驗教訓從新適當地進行編碼。
例如,假定你在製做一個應用,其用途是幫助運貨人肯定怎樣把不規則的箱子裝入集裝箱。
除了考慮其餘一些問題,你還須要設計直觀的用戶界面,而你用於肯定最優集裝箱方式的算法很是複雜。
你能夠在GUI工具中爲最終用戶製做一個用戶界面原型。你的代碼只能讓界面響應用戶操做。一旦用戶對界面佈局表示贊成,你能夠把它扔掉,用目標語言從新對其進行編碼,並在其後加上商業邏輯。與此相似,你能夠爲實際進行裝箱的算法制做原型。你能夠用像Perl這樣的寬鬆的高級語言編寫功能測試,並用更接近機器的某種語言編寫低級的性能測試。不管如何,一旦你作出決策,你都會從新開始在其最終環境中爲算法編寫代碼,與現實世界接合。這就是原型製做,它很是有用。
曳光代碼方法處理的是不一樣的問題。你須要知道應用怎樣結合成一個總體。你想要向用戶演示,實際的交互式怎樣工做的,同時你還想要給出一個結構骨架,開發者能夠在其上增長代碼。在這樣的狀況下,你能夠構造一段曳光代碼,其中含有一個極其簡單的集裝箱裝箱算法實現和一個簡單算法、但卻能工做的用戶界面。一旦你把應用中的全部組件都組合在一塊兒,你就擁有了一個能夠向你的用戶和開發者演示的框架。接下來的時間裏,你給這個框架增長新功能,完成預留了接口的例程。但框架仍保持完整,而你也知道,系統將會繼續按照你第一次的曳光代碼完成時的方式工做。
其間的區別很是重要,足以讓咱們再重複一次。原型製做生成用過就扔的代碼。曳光代碼雖然簡約,但倒是完整的,而且構成了最終系統的骨架的一部分。你能夠把原型製做視爲在第一次曳光彈發射以前進行的偵察和情報蒐集的工做。