對架構(gòu)師的一些理解
在討論架構(gòu)之前,我們先上道菜,青椒土豆肉絲,這道小菜味道還是不錯的,自私點了,不考慮您是否喜歡,今天就上它了。
準(zhǔn)備原材料:食用油、青椒、土豆、肉絲、大蔥、香醋、雞精和食鹽。當(dāng)然根據(jù)需要您可以再加入其他輔料。把青椒、土豆、肉片都切成絲,大蔥切好,OK,一切準(zhǔn)備就緒,開火,往鍋里加油,等油熱后,放切好的蔥片,聞到蔥香,放肉絲,稍微加些醬油,爆炒,接著放土豆絲和青椒絲,等八成熟,撒些雞精和食用鹽,出鍋。
細(xì)心的讀者可能發(fā)現(xiàn),剛開始的時候我好像并沒有準(zhǔn)備醬油,是的,我確實沒準(zhǔn)備醬油,坦白的講,有時候當(dāng)鍋里的油熱的時候,我突然發(fā)現(xiàn)蔥忘記洗了,更談不上切成蔥片了,此時我會匆匆忙忙的去洗,去切,甚至有時候慌里慌張的把手給切破。
通過我們做上面的一道菜,我們總結(jié)了以下幾點:
總結(jié)1:巧婦難為無米之炊,我們要想做好這道菜,需要原材料;
總結(jié)2:這些原材料以時間為軸心他們彼此之間是有順序關(guān)系的;
總結(jié)3:可能在某一步驟里,我們突然想添加些事先并沒準(zhǔn)備好的原材料;
總結(jié)4:一旦形成熱油鍋,似乎你要在這么短的時間內(nèi)完成這些動作,做過飯的朋友更能體會到這句話。
言歸正傳,以軟件的思想去考慮上面的業(yè)務(wù)(事情),原材料,你可以理解為類庫;順序關(guān)系,你可以通過事件來描述;事先并沒準(zhǔn)備好的原材料,你可以通過接口(抽象類、虛函數(shù)等),讓用戶重載去實現(xiàn);到這里你會發(fā)現(xiàn),一旦打開“煤氣”,去“引爆”預(yù)先設(shè)計的事件、接口,就好比多米諾骨牌一樣一個接一個的傳遞下去,在某一時刻,它會檢查是否放了“蔥片”、是否放了“肉絲”,不好,“食用油”你就沒放,還炒什么菜,扔出異常……
是的,上面就是框架,要想設(shè)計一個好的框架,看來我們首先要知道“青椒土豆絲”的做法,它大概需要哪些“原材料”,以及這些“順序關(guān)系”該如何通過具體的語言去實現(xiàn);當(dāng)然了,要炒出“不同的菜”,具體的原材料和順序關(guān)系又是不同的。下面通過分析幾個大家比較熟悉的框架來更詳細(xì)的說明。
MFC框架:
MFC中的框架思想采用了MVC的思想,其中CWinApp是全局型的,整個程序的引爆也是其在“搞鬼”,在其內(nèi)部有指向文檔模版的指針,而模板又攘括了視圖、視圖的管理者(就是那個frame)和文檔類,順序關(guān)系是靠消息泵來推動。通過下面的調(diào)用關(guān)系可以看到各個類的“相互依存”(說明:下面的表摘自網(wǎng)絡(luò))
從該對象 | 如何訪問其他對象 |
全局函數(shù) | 調(diào)用全局函數(shù)AfxGetApp可以得到CWinApp應(yīng)用類指針 |
應(yīng)用 | AfxGetApp()->m_pMainWnd為框架窗口指針;用CWinApp::GetFirstDocTemplatePostion、CWinApp::GetNextDocTemplate來遍歷所有文檔模板 |
文檔模板 | 調(diào)用CDocTemplate::GetFirstDocPosition、CDocTemplate::GetNextDoc來遍歷所有對應(yīng)文檔 |
文檔 | 調(diào)用CDocument::GetFirstViewPosition,CDocument::GetNextView來遍歷所有和文檔關(guān)聯(lián)的視圖;調(diào)用CDocument:: GetDocTemplate 獲取文檔模板指針 |
視圖 | 調(diào)用CView::GetDocument 得到對應(yīng)的文檔指針; 調(diào)用CView::GetParentFrame 獲取框架窗口 |
文檔框架窗口 | 調(diào)用CFrameWnd::GetActiveView 獲取當(dāng)前得到當(dāng)前活動視圖指針; 調(diào)用CFrameWnd::GetActiveDocument 獲取附加到當(dāng)前視圖的文檔指針 |
MDI 框架窗口 | 調(diào)用CMDIFrameWnd::MDIGetActive 獲取當(dāng)前活動的MDI子窗口(CMDIChildWnd) |
您可以試著聯(lián)想“炒菜”的過程去思考上面的這張表,如果您真的理解了,我相信您會覺得他們之間沒有什么區(qū)別(不過坦白來講真的理解并沒有那么容易),好吧,你可能又發(fā)出疑問?如果去做“填空題”?在MFC里是通過處理消息來實現(xiàn)。那么為什么沒有采用虛函數(shù)及多態(tài)來實現(xiàn)?這個問題問的很好,不過我沒打算在這里進(jìn)行說明,你可以在侯杰的《深入淺出MFC》里找到答案。(我不是有意來推這本書,實在沒看到其他更好的)??赡苣銖膩頉]接觸過MFC,那就不要去思考了,下面舉另外一個例子。
asp.net:
asp.net的webForm以其容易上手而著稱,如果你深入的理解了其頁面生命周期后,你會發(fā)現(xiàn)這好像又是在“炒菜”,而我們要做的只是在不同的“炒菜步驟”內(nèi)去定制我們的一些小創(chuàng)意,可能在Page_PreInit里、在Page_Init里、在Page_Load里或其它事件里,無論如何,您逃不過如來佛的手掌心,你要做的工作,就是在這些事件里去定制,換句話說,你搞不出來“宮保雞丁”,想搞個“宮保雞丁”該怎么辦?asp.net MVC 粉墨登場……自己可以分析下,這里就偷懶省略了。
從炒菜到實例分析,現(xiàn)在我們基本上對軟件架構(gòu)有了一個大概的認(rèn)識:
認(rèn)識1:框架架構(gòu)是有邊界的,不光如此,你必須有全局的概念才能去設(shè)計框架。所謂邊界是針對不同的業(yè)務(wù),比如MFC是針對傳統(tǒng)的桌面程序,當(dāng)遇到WEB時,似乎就不怎么靈光了,不然微軟不會花費那么多功夫去推.NET。
認(rèn)識2:框架的實現(xiàn)是組件的相互關(guān)聯(lián)(通過接口,事件等),如果你手里有些基本的類庫,不要告訴我是框架。
認(rèn)識3:設(shè)計框架不是為了好玩(其實它本身并不好玩),因為你要為“兩個人”負(fù)責(zé):業(yè)務(wù)和使用框架的人。建立在你框架上的應(yīng)用必須能解決你實際的業(yè)務(wù)問題,同時要考慮怎么樣讓開發(fā)人員能“懶惰”下來,比如就是做做填空題。
認(rèn)識4:設(shè)計框架要有一個好的框架思想,和具體語言無關(guān),但你必須明白,不同的語言,甚至相同的語言去實現(xiàn)的方式又不相同,比如MFC采用了宏來實現(xiàn)消息機(jī)制,而asp.net內(nèi)采用虛函數(shù)等來實現(xiàn)多態(tài)。
認(rèn)識5:你要時刻明白,接下來可能炒的菜就是“宮保雞丁”,也就是說你要知道自己在干什么,要熟悉自己的“業(yè)務(wù)”,比如當(dāng)你設(shè)計MFC框架時,你要考慮一個傳統(tǒng)的桌面程序要解決的大部分問題會是什么?比如打印,比如進(jìn)程通信,比如文件操作,比如音視頻,數(shù)據(jù)庫操作,ole,等等。同樣的,當(dāng)你來設(shè)計ASP.NET時,因為這道菜是針對HTTP的,這個時候你如果連HTTP是什么都不知道,我想你炒不好這道菜。
OK,我想這篇文章該結(jié)束了,因為我們的“菜已炒好”,如果你認(rèn)真仔細(xì)的看到這里,估計已經(jīng)浪費了你近五分鐘的時間,希望能給你帶來點思考,比如:架構(gòu)師就是來“炒菜”,可能吧,也可能我的觀點并不完全正確。不過我歡迎聆聽每個朋友對架構(gòu)的理解。謝謝。
原文鏈接:http://www.cnblogs.com/daoxuebao/archive/2012/06/14/2549967.html 【編輯推薦】