或許我們做錯了,但絕非一無是處

是的,過度設計的現象普遍存在。回到90年代中期,當我開始入行開發者行業時,我的目標就是成爲一個架構師。任何認真的開發者都不會在選定自己喜歡的設計模式之前就開始寫代碼。我們會在選好設計模式之後纔開始思考怎樣將業務需求融合進去。是的,我們會先弄出架構,然後是宏設計(層)和域模型(包括UML圖表),接下來才思考業務需求和詳細的用例。沒錯,那個時代,用例真的不是什麼大事。我們的基本流程和衆多可選流程中有一長串的用例。

90年代是開發者們羣情振奮的時期。70和80年代還在學術論文層面上的一些結構化設計,以及互聯網,最終都在90年代實現了。那個時期裏,還出版了基本面向對象編程的書,至今在很多領域裏還是新鮮的概念。

我依然記得我們撲在畫類、序列、組件、部署和很多其他圖表上的無數個月,我們總在嘗試想出未來某天我們將打造出的軟件的最佳設計。我們也建立了一些原型,因此我不能說在規劃階段我們沒有做任何的編程或試驗。當然,所有來自於原型的經驗教訓最終都會反饋到我們的圖表中。

除了內部設計,90年代還是分佈式系統大爆炸的時期。我們有了CORBA(公共對象請求代理體系結構)和DCOM(分佈式組件對象模型),有了客戶端/服務器(C/S)和多層級架構。我們在使用數據庫作爲應用程序間通信點上學到了單點故障。是的,我們在這上面栽過大跟頭。我們學會了怎樣創建“服務”——SOA(面向服務架構)概念迅速興起。我們學會了考慮可擴展性和安全性。很多政府和銀行以外的項目也變得非常巨大和複雜了。

大多數充滿激情的軟件開發者的目標,都是創造出一個超棒的設計;這也是通往架構師和職業昇華的道路。我們必須學習,要在軟件設計上做到最好。我們必須對結構化設計和麪向對象設計都有着深度理解。我們必須瞭解分佈式系統的基本原則。我們必須非常熟悉所有層級的內聚和耦合。我們必須理解協變與逆變。我們必須學會設計包含了契約與不變量的組件邊界。我們必須學會理解業務語言中的動詞和名詞,並將它們映射進軟件中。如果不知道怎樣在關係數據庫中對數據建模,不知道怎樣讓查詢表現良好,那就根本過不了入職面試那一關。我們必須能在合適的粒度定義自己的專有協議,以便能讓其他系統更容易地使用它們,同時,還要能處理輸入輸出(I/O)和帶寬問題。是的,我們花費大量的時間來幹這事兒。

90年代 的軟件開發基本圍繞設計和架構展開。而且,還必須用UML來完成。

但是,雖然我們學會了怎樣設計,卻敗在了很多其他方面。我們開發得不夠快。事實上,在某些項目中,我們根本沒能產出任何東西。大多數時候,我們花費在拿出一份完美設計上的所有腦力勞動都完全打了水漂——缺乏快速反饋以及對業務發展的無力應對。我依然記得在一行代碼都還沒開始寫之前就用來控制需求變更的巨大電子表格。是的,我們報銷了大量的時間。很多很多次地報銷掉了。

快進20年,我們中的有些人意識到了之前所做的是錯的。於是,我們在工作方式中引入了敏捷開發(Agile)、精益開發(Lean)和其他多種開發原則和實踐。我們的工具包中加進了很多新的設計和架構技巧。我們引入了新的技術。我們融合了與業務協作的不同方式,開發團隊構建方式也有了創新。我們認識到,儘管設計非常重要,但沒有什麼東西比持續推出軟件更重要的。我們學會了怎樣獲得反饋並進行迭代。我們明白了自己有責任測試自己的代碼。我們懂得了必須在生產中爲軟件提供支持。我們知曉了創建原型再摒棄的價值。我們瞭解了實驗的重要性。但是,我們同樣深深領會到,即便要以更好的方式工作,這些年來我們所獲得的所有設計技巧也不用全都扔掉。我們沒必要放棄我們那個時代,70、80、90年代軟件設計上的衆多出色成果。但,我們學到的最重要的一課,就是:上下文才是決定性的,軟件設計就是在權衡而已。沒有產品,設計毫無意義。那麼,我們就要不斷產出沒有堅實的設計基礎的代碼嗎?我可不這麼認爲。

今天的軟件設計中,我所看出的最大的問題,就是二元思維。如果X不行,那麼Y必然很好。如果X適用於A公司,那我們也一定能用。如果某個著名人物在一場45分鐘的演講裏說了什麼東西,或者我們在博客裏看到了什麼東西,那肯定是真的。例子太多,不勝枚舉。

二元思維引發的另一個常見錯誤,就是堅信軟件項目的所有功能都具有同等的複雜度,一個設計選擇就能通吃。但真相是:某些功能相當簡單,某些十分複雜,其他跟多的則處於兩者之間。有時候,複雜性存在於實現階段;其他時候則會在理解和建模階段出現。有時候複雜性在於弄清我們應該做出個什麼東西。其他時候則在於與別的系統的集成上。就算是同一個功能,不同部分在複雜性上也有很大的區別:一些部分可能很小,可以快速實現,而其他部門有可能極端複雜,需要預先考慮很多。某些功能很淺,幾行代碼就搞定,其他則很深,要用到多個模塊,上千行代碼。非功能性需求也會讓簡單功能的部署變得相當複雜。而有趣的是,以上種種都在同一個軟件項目中碰上。因此,如果我們認同軟件項目中不同功能有着不同的複雜度和規模,那麼,我們就不能將二元思維應用到軟件設計上——一個相當複雜的軟件項目是不可能用單一設計方法搞定的。

我們生活在一個信息觸手可及的世界。谷歌搜索一下,我們就能搜到很多現成的解決方案。我所恐懼的是,作爲一個產業,我們正在喪失思考的能力。我們正在喪失研究並作出我們自己的選擇的能力。我們越來越多地依賴於現成的解決方案。我們總是在走捷徑。要我說的話,我會把這些所謂的捷徑稱作“Stack Overflow(一個與程序相關的IT技術問答網站)”解決方案。

對某些人而言,軟件設計就是過度設計的同義詞,這讓我很傷心。另一個讓我傷心的認知是,“根本沒有設計”正成爲敏捷開發、精益創業和快速交付的同義詞。我不覺得良好軟件設計、敏捷開發和精益原則的發起人和倡導者們的本意是這樣的。過度設計不是件好事,但沒有設計不也很糟麼?簡單不意味着扯淡。簡單代表的是我們當下所知道的剛剛好的設計,而不是少到可憐或者根本沒有的設計。套用愛因斯坦的話:軟件設計應該儘可能簡單,但不能過於簡單了。或者,另一種表達方式:代碼應該是良好設計的,而不是過度設計的。

過去幾年裏我與很多開發者聊過,也複查了很多的代碼,我主要擔心的是,我們正在發展一種黑客文化。我見過的從業不足10年的很多開發者,都幾乎沒有什麼良好軟件設計的知識。當然,他們自己不那麼認爲。如果你覺得我是在誇大其詞,那就去讓你團隊中的開發人員解釋一下什麼是內聚,以及內聚的不同層級。問問他們共生性、協變、逆變的含義。問他們耦合的不同等級和類型。問他們什麼是契約式設計和不變量設計。對那些聽說過面向對象設計SOLID原則的人,問他們SOLID原則的出處。今天的很多開發者認爲設計模式不好。那就讓他們描述幾個模式,說出它們的異同,以及什麼情況下應該或不應該用某種模式。問問他們不同的模式分類法。讓他們說出橋接模式、適配器模式和中介模式的差異。訪問者預期要解決什麼問題?問問他們什麼是備忘錄模式。如果他們解釋不出,那他們又怎能稱設計模式不好呢?

今天的很多開發者都沒有意識到軟件設計基礎都是在70、80、90年代鋪設的。其他開發者則傾向於無視這一事實:這就是過度設計,我們不需要。好吧,我尊重個人意願。那我們爲什麼依然保留了那些糟透了的軟件呢?難道今天的做出的軟件就真的比20年前做出的好嗎?爲什麼開發者今天依然在用測試驅動開發模式(TDD)艱難設計代碼?爲什麼我們依然在討論遺留代碼?對我而言,遺留代碼就是設計很爛、難以測試和維護的代碼的代名詞。

我絕非在爲過度設計或浪費時間畫UML圖表辯護。我想說的是,我不會花幾個小時去設計核心領域內部類,也不會試圖在開始編碼之前不考慮整體設計就去打造一個企業應用並一次次測試。設計是軟件開發中的重要一環。如果我要打造一個與其他很多應用共存於同一個生態系統內的應用程序,或者一個揹負沉重非功能性需求的應用,又或者一個需要遵從很多規則的應用,好吧,我當然會在動工之前認真考慮它的整體架構(宏設計),但我也會邊開發邊測試它的功能(“微層級”)。設計存在於各個層級:從前期的架構層級,到即時的作爲我TDD流一部分的微層級。決定設計的量是個技術活兒——關鍵就在找到拐點。

軟件設計是軟件開發中最重要的技術之一。好的設計能讓開發者相互協作,業務功能可以隨時增加和改變,還能擁有可靠的自動化測試。隨着經驗的積累,我們會學會怎樣快速找到問題點,估算出應該花費在解決問題上的時間。我們還明白,大多數設計決策應該在最後時刻再做出,這意味着,在還沒掌握問題的足夠情報前,我們儘量不過早地綁定到某個設計上。

這就是爲什麼我說我們90年代所做的是並非都是無用功的原因。儘管我們過度設計,儘管我們產出不多,但我們學會了怎樣設計。我們學會了怎樣爲我們自己考慮。我們學會了怎樣研究。我們學會了怎樣思考權衡。花了些時間,但我們確實學會了怎樣避免二元思維,節制我們對於新潮流的過度興奮。強大的軟件設計基礎和敏捷開發及精益開發原則和實踐的結合,讓我們不僅可以快速拿出軟件,還能持續推出軟件。

我們的目標是支持業務敏捷性,而這能通過可以持續部署到產品中的軟件來達到。一次性部署軟件沒什麼難的,但想要幾個月甚至幾年時間裏保持每天都往產品中部署軟件,就沒那麼簡單了。我們需要很多守則和工程設計來達到持續部署的目標,也就讓軟件設計和TDD成爲了我們必須掌握的兩大重要技術原則。

作者:桑德羅·曼卡索(Sandro Mancuso),軟件工藝師,作家,倫敦軟件工藝社區(LSCC)創始人。幼年即開始寫代碼,但直到1996年才正式入行。曾爲初創公司、軟件作坊、產品公司、國際諮詢公司和投資銀行工作。

其職業生涯中曾有機會參與多種多樣的項目,用過不同編程語言、技術,跨越很多不同行業。桑德羅在向不同規模的公司企業引入軟件工藝理念和極限編程實踐上有着豐富的經驗。由於在發展和傳播軟件工藝上的傑出工作,桑德羅蜚聲國際,常被邀請參與各種全球性會議並發表演講。他的職業抱負,是通過幫助開發者進一步關注和改善自身技藝,來促使軟件產業向前發展


原文地址:http://www.lindukj.cn/news/archives/829

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章