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

2022-09-03 02:12:13 字數 3959 閱讀 6221

是的,過度設計的現象普遍存在。回到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成為了我們必須掌握的兩大重要技術原則。

收集中你做錯了什麼?

研究報告常提出因為a的原因引起了b的現狀。例如一些報告說,吸菸多少跟學校的成績相關。報告還會給出一些看起來2者的相關的資料,但是是否就能表示成績差是吸菸導致?或者成績差而導致吸菸?還是其他原因?單從統計的關聯性推斷出因果關係正確嗎?這對軟體開發統計分析有什麼啟發?我常常強調,在利用統計來做分析資料時...

如此優化!我們錯了嗎?

我們認為影響 排名的關鍵性問題是什麼?關鍵詞的密度 內容的更新還是路徑的固定化等等,其實到最近筆者小丹開始思考,之前我們一直盲目的跟隨演算法規則的指向前進,結果 反而出現了很多問題,我們的優化觀點到底是對還是錯呢?在搜尋引擎不斷變更演算法的時候,我們也在用自己的優化技術進行跟進,以求 的穩定。不論是...

如果你很忙,你一定在什麼地方做錯了!

柏林研究專案 早在1990年初,由三名心理學家組成的研究小組突然拜訪了柏林藝術大學 位於西柏林市中心的一所久負盛名的藝術教育機構。他們此行的目的是為了專門研究小提琴演奏者。我們把這個組稱為優秀演奏者小組。violinist diana yukawa 為了便於研究比較,教授和心理學家也會從學校的其他相...