大道至簡

昨天看到博客園的一篇新聞《程序員的迴歸式進化》,該新聞非常有意思,展示了同一段“Hello World”代碼,一個1年編程經驗、一個2年編程經驗、一個3年編程經驗、一個5年編程經驗和一個10年編程經驗的不同寫法。這些寫法中,讓人啼笑皆非的是5年工作經驗的程序員編寫的代碼看起來如此的複雜、如此的有技術含量,而10年工作經驗的程序員編寫的代碼竟然和1年工作經驗的程序員是一樣的,真是有點諷刺,呵呵~~。


不過,笑過之後,還是讓我忍不住陷入沉思。本人已經寫了11年的C#代碼,寫了3年的Java代碼,還使用過彙編語言、C語言、Delphi、PowerBuilder、C++、ASP、PHP、C++ Builder等寫過不少代碼,經歷的項目和產品也不算少了。我一直在追求如何使軟件開發變得更爲簡單,這種簡單不僅僅是對於我自己,更是對於整個團隊。


企業級軟件天生就是複雜的,爲什麼呢?如果一個軟件市場不錯的話,那麼這個軟件總是會不斷的進行演化,代碼數量總是在不停的增加。以Spring爲例,0.91版本發佈時只有1萬多點代碼,1.0發佈時有2萬多代碼,1.2發佈時有4萬多,2.0發佈時有6萬多,2.5發佈時有7萬行代碼(以上數據參考《Java應用架構設計》),代碼越多意味着越複雜。如果這些代碼中,還存在技術債、設計腐化、循環依賴等各種內在的問題,那你想想看,如何使其迴歸簡單?如果你加入一家公司,不幸的要去維護一個現有的系統,你如何迴歸簡單?千萬別告訴我,你要重新編寫一套,這只是簡單的技術思維而已!


回過頭來,我們再看看那個5年經驗的代碼。其實該程序員的寫法沒有錯,他已經學會了如何使用DI進行解耦合了,猜得不錯的話,他也是學會了設計模式,甚至掌握了一些OOP的設計原則。但是如果整個應用系統都充斥了這樣的代碼,那我估計誰看誰發瘋!


那麼這個懂DI、懂設計模式、懂OOP設計原則的有經驗的程序員犯啥錯了?很簡單,我覺得他什麼錯也沒有犯,他只是依然缺乏經驗而已。


看了那個代碼,我覺得第5年寫的那個,其實最主要的是沒有考慮系統和業務角度去考慮變化和不變之處,而只是單純的體現了技術。


道法自然
操作系統的功能邊界是清晰的,而企業級開發的對象是人,人的需求是複雜的,所以功能也是多變的。
單獨的一個模塊,企業級開發沒有操作系統複雜,當模塊逐漸變成一張大網的時候,能從網裏脫身出來,就很不容易了。而且還要有時間的制約。




拋開團隊管理和協作層面,我們單從技術層面來考慮,想要使應用系統的開發變得簡單,有效的方法就是化整爲零,將複雜大系統拆分成小的、簡單的、能夠組合的“代碼塊”,簡化系統開發並間接提高軟件系統的可維護性和可擴展性。那問題是,這個“代碼塊”應該是怎樣的粒度?下圖是軟件系統“自上而下”架構圖(該圖參照《Java應用架構設計》),服務/子系統的粒度大,類的粒度小,系統的展現層粒度一般比較大,而數據訪問層粒度小。粒度越小,系統越抽象,越靈活;粒度越大,系統越簡單,可複用性越低,擴展性越差。


p_w_picpath


想要使系統開發變得簡單,選擇“模塊”作爲開發、複用粒度較爲合適,模塊符合高內聚、低耦合,在模塊內部,我們傾向於使用1年工作經驗或者10年工作經驗的代碼,模塊內部依賴關係較少,較爲清晰,不宜在內部搞太多的抽象。在我們的實踐過程中,模塊內部不會使用IoC,也不太提倡使用太多抽象,會使用非常直接、簡單的編碼規則,使1年經驗的開發人員能夠編寫模塊業務邏輯。那麼5年工作經驗的那些代碼適合在哪使用呢?


我的答案就是“模塊間的邊界”。通過對模塊間的邊界使用OOP的SOLID原則,能夠更大提高模塊的複用性和擴展性,同時還能夠保持模塊內部的簡單,這或許就是在技術層面迴歸簡單的一種較好的方法了!


企業級軟件系統的複雜,不僅僅是技術層面,相反,管理與團隊協作更容易影響系統的成敗。一個複雜軟件系統通常都是由團隊協作來實現的,一個完整的團隊通常有高級工程師、中級工程師和初級工程師,高級工程師負責架構和設計、中級工程師負責編碼、初級工程師僅是入門。有效的解決三種層次工程師的協作,儘量減少交互、協作、學習的成本,能影響後續的維護成本。在我看來,良好的協作模型應該促使三者的工作更加的Focus,專注於自己開發的業務邏輯。同樣的,模塊化也能夠很好解決三者的協作。一方面,通過模塊化,我們可以消除軟件架構(或者成爲統一架構);另一方面,高級工程師負責框架類模塊、中級工程師負責業務類模塊、初級工程師快速入門協助開發,三者可以進行並行開發,而且代碼互相隔離,互不影響。從這個角度看,初級工程師的入門速度也將極大提高。


因此,迴歸簡單的一個好方法就是:(1)化整爲零,將系統進行模塊化劃分;(2)在模塊內部保持簡單,使用1年或者10年經驗代碼,在模塊間交互部分的代碼使用5年經驗的編碼更是,應用OOP的SOLID、設計模式、SOA等抽象技術,提升模塊的可複用行和可擴展性。


@量子計算機
引用樓主園齡離10年還差3年啊。你現在知道要簡單是一個正確的方向了,等三年後你這麼幹,那就是做到了,怎麼做呢?
拋棄iOpenWorks,OSGi.NET等這些你現在還當寶貝的玩意,把你曾經的心血,當垃圾,然後呢?然後去使用Json,Restful,等這些小玩意,這就是真簡單了。

不要以爲做到簡單很容易,那是在割你的肉,樓主別受不了又刪貼啊。

你園齡已經快10年了,然道理解不了我的文章和那篇新聞的含義嗎?你真的覺得什麼都不用就最簡單了?我們就說車,有自行車、三輪車、出租車、小轎車,有低檔、中檔和高檔的車,單純用“Hello World”來搞點自行車的玩意可行,因爲簡單。你要是用“Hello World”來充斥着四輪車,可行嗎?現在搞出那麼多架構,那麼多框架,比如Spring,照你說的,都是沒有必要的大東西了。

我園齡7年,C#寫了11年,寫過幾十個項目,厭倦了系統不停變化,厭倦了團隊成員胡亂整代碼,也厭倦了複雜的東西。我原來在Sybase的一個同事,他已經工作了10幾年了,是框架的架構師,產品統一使用插件化/模塊化框架,產品組開發的是插件。我們開發插件的時候基本不需要和框架打交道,插件可以清晰分層,經歷那麼多人維護之後,插件還能繼續維護,這是另一種“簡單”,不是你說的那種“簡單”。企業級的軟件本身就是複雜的,不談想Eclipse這樣的大系統,我們做的能耗監控、熱力分佈式系統就不那麼簡單了,需要不停的進行需求變更,需要處理很大數據量。讓厲害的人負責抽象的部分,讓菜鳥負責簡單的功能,然後進行組合,這是以前的經驗告訴我的,我以前那些非常厲害的同事教給我的。我不是現在纔想簡單,早就想簡單了。想要簡單當然不容易,該抽象的需要抽象,該簡單的需要簡單,什麼樣的人適合做什麼合理分配,條理清晰。

iOpenWorks/OSGi.NET是我設計的,一方面是參照我以前的同事的架構思想,另一方面是參照OSGi強大的功能來做的。使用OSGi.NET框架不是用於支撐很複雜的技術,只是用於支撐更好的協作,更好的能讓高手寫抽象模塊、菜鳥寫簡單功能模塊,僅此而已,我就是想用這樣的框架來追求我以前接觸過的簡單。我們已經應用該框架3年多了,發展越來越好,我幹麼要將其當垃圾扔掉呢?OSGi.NET原理確實不簡單,但是誰需要去了解它呢?就像我們以前不需要去了解架構師設計的框架一樣。你不用倚老賣老,雖然你園齡比我長,我已經見過比你年齡更長的,從他們身上我學習更多。建議你以後可以多給別人提供意見,但是少給別人下結論,事實上,很多事情到你掛的那天你也不一定就是對的。


總結的非常好,老程序員的作用不是編碼,而是面對各種設計方案的時候,可以用經驗來權衡,考量,規避風險。
粒度,複雜度,這些東西,只有犯過無數次錯誤,有血的教訓的人,才能深刻理解重要性的,


確實如此,這些規則很多時候,說出來特別虛,但是確實是需要有教訓纔有深刻體驗。

一般而言,1~3年,還是學習基本技能,3~5年學點高級技能,10年的同志一般要做的是設計和架構、編寫高級代碼,底下還有團隊,如果你帶了幾個團隊,就知道簡單有多重要了,底下的人啥都能給你折騰出來,只有清晰簡單的規則才能長遠。


爲什麼企業級的開發就一定要很複雜,難道比操作系統內核還要複雜?

不復雜的話,那麼多的軟件開發方法、開發技巧是用來幹麼的?非得操作系統才需要嗎?


企業級軟件系統在不停的演化,對產品質量要求高,涉及開發人員多,當然,技術本身也較爲複雜。


項目團隊中,難免 會有 能力強,能力差 的隊員。

如果兩種人 都 做 同一種事:只是 能力強的做的多,能力差的做得少 —— 最後的結果往往是,能力強的特別累,能力差的特別閒;

所以,將 粒度細化, 能力強的給能力差的 提供架構,降低 能力差的隊友的開發門檻:讓能力差的隊友 也能 在不拖延時間的基礎上,實現 能力強的隊友 才能實現的 複雜功能;

——這纔是軟件架構之道呀。

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