浅谈我对框架的理解
原文鏈接:http://www.felix021.com/blog/read.php?1793
有少量修改,如有疑問,請訪問原作者...
Def:
框架(Framework)是整個或部分系統的可重用設計,表現為一組抽象構件及構件實例間交互的方法;另一種定義認為,框架是可被應用開發者定制的應用骨架。前者是從應用方面而后者是從目的方面給出的定義。 可以說,一個框架是一個可復用的設計構件,它規定了應用的體系結構,闡明了整個設計、協作構件之間的依賴關系、責任分配和控制流程,表現為一組抽象類以及其實例之間協作的方法,它為構件復用提供了上下文(Context)關系。因此構件庫的大規模重用也需要框架。?????? 一個完美的框架,應該是一個實現了對修改關閉,對擴展開放的框架。需要修改,意味這這個框架仍然存在瑕疵;不適合擴展,那就沒有被稱為框架所需的內涵。當然,完美的框架是不存在的,也沒有一個框架能夠滿足所有的情況,所以需要根據具體的情況來做出選擇。
Range:我覺得做出這個選擇的最重要標準是系統的規模。
??? ?? 對于一個小型系統,也許是一次性的(沒有多少擴展需求),或者代碼比較少(修改起來比較容易),那么框架的存在就不一定是必要的了。不論是自己設計一個框架,抑或是學習并采用一個現有的框架,都需要耗費比較多的時間精力,對于一個小型系統而言,很可能得不償失。當然,不需要框架并不意味著可以隨意開發(隨意開發的過程是痛苦的,越往后越明顯,felix深有感受...),高內聚低耦合等基本的設計原則還是必須遵從的,這樣能夠使開發過程更簡單。更嚴格一點說,一個良好的設計本身就帶有一些框架的性質。
?? ? ? ? 對于一個中型系統,如果規模雖然稍大,但是仍然可以在少數幾個人的掌握之下,那么一個強大的框架對開發是有相當助益的。在這種情況下,學習框架的開銷是可以接受的,一次投入多次產出:在掌握了框架以后,每當需要增加新的功能的時候,只需要按照框架的規則寫一個模塊并插入到系統中,多余的事情都由框架來完成,非常輕松。
???????? 對于一個大型系統,其規模已經大到不是幾個人可以掌握的了,那么在開發之初對框架的選擇是至關重要的。因為當系統大到一定規模再更換框架,在很多情況下是不現實的,所以在開發之前就必須有足夠的考慮。一個強大的框架是必須的,但我覺得這還不是全部:這個框架還必須簡單。俗話說計劃趕不上變化,當初設計得再好的功能,逐漸也可能會不適應后來的需求(PM一句話,RD兩行淚=.=),以至于成為整個系統的累贅。所以框架還必須要簡單(無為而治)——這個簡單不是說框架需要提供少的功能。引用講述Unix設計哲學的一段話:
Strategy:策略與機制分離???? 這些是非常理想化的選擇,但是實際中又存在許多難以避免的問題。
其一,溫水煮青蛙
這個寓言大家都耳熟能詳了,雖然其真實性有待驗證,但是其寓意還是很有警示意義的。一個系統的規模并不一定是剛開始的時候就可以知道的。比如創業的小公司,剛開始可能只是設計一個小型或者中型的系統,直到某一天發現系統負載或者是其擴展性已經或者將在可見的未來無法滿足要求。這時候為了發展只能進行底層的重構。
其二,機制和策略的矛盾
Unix哲學考慮得很好,程序應該分成機制和策略兩塊,但是將這二者完全劃分清楚未必是好的,甚至是不可能的。如果框架完全不干涉策略的實現,那么意味著每一個模塊的開發都會有更多的工作量。如果框架過多地干涉策略,那么意味著框架過于復雜,掌握框架的代價更高。所以這里存在需要權衡的地方,而權衡的標準,還是的得考慮系統的規模和復雜性。于是又回到上一個問題了。
其三,...
需求的不確定、某個語言的局限這樣一些具體的問題,也許不應該放在這里,但是在實際的開發和維護過程中,他們又的確會困擾開發者。甚至讓人頭疼。
Conclusion:----
說了這么多,感覺有點虛,因為沒有什么特別具體的例子。公司里的項目不適合拿來討論,但是正好前幾天跟同事聊到一個例子,覺得比較適合放在這里說說。
這個例子就是C++,和C。最近一段時間我對C++有一些排斥,所以很難保證我下面將要說的內容的中立性,有任何問題歡迎探討。
我覺得C++本質上就是C的一個框架。C++包裝了C語言,提供了一些方便開發的特性,比如對面向對象的支持,比如對泛型的支持。根據上面提到的命名方式,我們可以認為這些特性就是這個"C框架"提供的機制,而C++程序員開發相應的程序,就是使用這些機制來完成其特定的策略。另一方面,C++不僅提供了機制,還在一定程度上影響了策略的實現。
比如說,在C++中,類的成員函數是否具有virtual屬性,決定了這個類(的這個成員函數)是否可以實現多態。當然,這可以看作是一種機制的實現,但是它不可避免地影響了具體的策略。更特別的是,如果一個被繼承的類的析構函數不具有virtual屬性的話,可能程序在運行過程中會出現內存泄漏。
比如說,當你編寫一個inline函數的時候,你可能期望它總是被inline,但是可能由于某些你不知道的限制,實際上inline屬性并沒有生效,它還是作為一個函數被反復調用。
再比如說,當你使用一個模板的時候,你可能不會考慮到這些模板對內存的占用。但實際上,模板的每一次特例化,都會使得幾乎相同的函數在內存中存在兩份拷貝(也許這個例子有些牽強)。另一個模板的例子是在特例化的時候沒有特別注意類型,比如說make_pair(1, 2.0)實際上創建了一個pair<int, float>,而不是pair<float, float>。
這些是多少都可以算做是這個C框架不僅提供機制,還影響策略的例子。我相信還有很多類似的例子是我不知道的,但是糟糕的是,要掌握這個C框架的代價太大。這也就是我近來對C++產生排斥感的主要原因(另一個原因是我擔心C++用多了,以后寫代碼會越來越懶~~~)。
說了這些不是想說C++是多么不堪、不能使用,去年暑假有很長一段時間我在仔細學習STL,其中有很多很偉大的設計。從這個角度來說,對C++我是心存敬畏的。從框架的角度來看,C++實際上是一個很強大的C框架,很適合快速開發,比如寫一個acm程序,我肯定用C++,好好用上STL。做一個小型的系統,我也許也會選用C++。我只是覺得,這個強大的框架做得不夠簡單,如果要考慮大型系統的開發,務必要仔細權衡。
---
最后,使用一個很著名的設計原則來結束這篇日志:
KISS: Keep It Simple, Stupid.
--
轉載請注明出自 http://www.felix021.com/blog/read.php?1793 ,如是轉載文則注明原出處,謝謝:)
RSS訂閱地址: http://www.felix021.com/blog/feed.php 。
后記:關于對庫和框架的選擇問題:
????? 從本質上說C++是C的一個語法擴展庫,只是納入了語言標準;正如boost是C++的預備役庫,假以時日 boost 有可能成為標準庫,即C的C++ 框架的一部分;
???? 其中boost庫的構建使用了標準框架,而這個庫又構成C++擴展框架的一部分;
???? 而對于程序構建,一個現成框架 只能構建一個模式的 系列軟件;而庫的使用 可以有任意發揮的空間,即必須自行設計框架。
??? 最后:程序員的時間比機器的時間寶貴的多...這就是為什么選擇C++的原因....
總結
- 上一篇: 路特斯汽车宣布因亏损严重裁员 200 人
- 下一篇: open source project