软件的本质
http://blog.csdn.net/pitt_xiong/article/details/7851368
軟件是一種固化的思維。其根本組成是概念和邏輯。軟件世界中的一切的故事始于一個機(jī)器模型,而這個基本的機(jī)器模型并不復(fù)雜,甚至可以用三個關(guān)鍵概念來概括:指令、數(shù)據(jù)以及棧。其邏輯也比較簡單,即按照指定的順序,逐步執(zhí)行各條指令。但也就是這樣一個簡單的模型,支撐起了整個軟件的世界。軟件構(gòu)建的過程就是從客觀世界中的概念和邏輯向機(jī)器模型逐步進(jìn)行映射的過程。由于編譯器(或解釋器)的存在,最后一重映射已經(jīng)被無限簡化,因此我們可以認(rèn)為以編程語言為載體的代碼即是固化后的思維,包含了所有固化后的概念和邏輯。
? ? ? ?為完成這一任務(wù),首先軟件的邊界必須清楚,即“要轉(zhuǎn)換的究竟是什么”必須盡可能明確,此即需求開發(fā)的根本任務(wù)。從需求向最終代碼的映射可以稱為軟件構(gòu)造。需求開發(fā)的結(jié)果:規(guī)格說明和軟件構(gòu)造的結(jié)果:代碼表述的實(shí)質(zhì)上表述的是相同的東西,所不同的只是視角,表達(dá)方法和詳盡程度。需求開發(fā)姑且不論,軟件構(gòu)造即在確定的范圍內(nèi)打造概念的邊界和定義概念間的邏輯關(guān)系的過程。
? ? ? ? 打造概念邊界時原則可以有許多,但手段只有一個,即抽象。從本質(zhì)上講,抽象是一種認(rèn)清事物本質(zhì),并進(jìn)行歸類的過程。與抽象相對的是具體,但抽象的來源也是具體。假使我們需要對【人】這一名詞進(jìn)行定義,那么必然是要從張三,李四等等具體的人身上抽取共通特征,而后才能完成定義。最終結(jié)果是【人】這一概念來源于張三,李四,但又不是張三李四。這樣一個從具體的事物中抽取共性,再進(jìn)行命名的過程就是抽象。
? ? ? ??我們常說的功能分解(Function Decomposition),抽象數(shù)據(jù)類型(ADT),面向?qū)ο?#xff08;OO)都可以看做是對事物進(jìn)行抽象的具體方法。但不管使用什么樣的方法,打造概念邊界通常并不容易。這種困難起源于概念本身的邊界并不清楚,存在模糊性。比如:當(dāng)我們描述一本書的時候,那么這本書是否被借出了這種信息,是既可以作為書的基本信息的一部分,也可以通過查閱借閱人的信息來存儲的。對此,哲學(xué)上的表述是:世上萬物是運(yùn)動的,聯(lián)系的,而非靜止的,孤立的。
? ? ? ?更困難的是一旦切換視角,相同的概念又可以有多種劃分方法。好比說,我們可以很容易界定什么是人,什么是猿,但當(dāng)我們試圖把人猿歸類的時候就依據(jù)我們的視角進(jìn)行抉擇。因為它似乎是人,似乎是猿,卻又更是人猿。打造概念邊界時正是類似人猿這類概念讓我們犯難。有些問題甚至只有選擇而沒有答案。莊子對這種事情的觀點(diǎn)是:自其異者視之,肝膽楚越也;自其同者視之,萬物皆一也 。
? ? ? ?也正因此編程是一種實(shí)踐多于是一種理論。
? ? ? ??我們可以抽象出一些指導(dǎo)性原則,比如開閉原則,比如里氏代換,比如高內(nèi)聚低耦合,但一旦面對現(xiàn)實(shí)時卻只能具體問題具體分析。也許有人認(rèn)為這里所說的澄清概念邊界專屬于面向?qū)ο?#xff0c;其實(shí)不是。當(dāng)你決定某一組函數(shù)專門負(fù)責(zé)文件操作時,你同樣是定義了【文件操作】這樣一個概念的邊界。包,類,模塊,數(shù)據(jù)結(jié)構(gòu),方法等等這些名詞都可以對應(yīng)到一個個具體的概念,是抽象這一工作的結(jié)果。
? ? ? ?我們把概念之間的關(guān)系定義為邏輯。而概念間的邏輯關(guān)系可以被分為兩類:一類是概念所固有的,基本不受具體應(yīng)用影響的靜態(tài)關(guān)系。比如:人是比老師或?qū)W生更為泛化的概念,老師或?qū)W生都需要有一個名字。這就是我們常說的繼承,包含聚合(整體與局部)等。需要特別一提的是框架(或設(shè)計模式)更多的體現(xiàn)的是一種靜態(tài)關(guān)聯(lián)關(guān)系??蚣馨讶中?#xff0c;共通的部分抽象出來,固定在框架之中,把局部的,需要定制的東西開放給用戶,來應(yīng)對變化。與這種靜態(tài)的邏輯關(guān)系相比,具體化的概念之間的動態(tài)關(guān)系顯的更為繁雜。如果說概念間的靜態(tài)關(guān)系體現(xiàn)的是一種預(yù)先存在的必然關(guān)聯(lián)的話,那么概念間的動態(tài)關(guān)系體現(xiàn)的則是實(shí)現(xiàn)具體功能時體現(xiàn)出來的偶然關(guān)聯(lián)關(guān)系。假設(shè)說我們要做一個簡單的監(jiān)控系統(tǒng)。那么大致會衍生出下面幾個方面的概念(模塊):
1 照相機(jī):負(fù)責(zé)拍照
2 圖像處理:負(fù)責(zé)分析照片中是否有異常
3 數(shù)據(jù)庫:用于存儲過往的記錄
4 報告功能:一旦發(fā)現(xiàn)異常,對相關(guān)人等進(jìn)行通知
5 控制器:根據(jù)既定的處理流程,使程序動起來。
6 ... ...?這個時候,控制器和照相機(jī)(或數(shù)據(jù)庫間)的關(guān)聯(lián)則是一種偶然關(guān)聯(lián),是動態(tài)關(guān)聯(lián)關(guān)系。把照相機(jī)替換為攝像頭也無不可。
對照實(shí)現(xiàn)來說的話,照相機(jī)的實(shí)例可以通過控制器的接口傳入,也可以在控制器的方法中創(chuàng)建,但如果把照相機(jī)作為控制器成員,則和這些概念間既有的關(guān)聯(lián)關(guān)系向背離,耦合度會有不必要的增加。
? ? ? ??在動態(tài)關(guān)系中第一重要的是動作的時序,即先后順序。
? ? ? ?時空的特征決定了這世界上大多的事情皆有因果,也決定了程序中凡事必有先后。當(dāng)我們明確了先做什么,再做什么,最后做什么之后,我們才能對事情真正有所把握。不管采用什么設(shè)計方法,都要讓這類路線盡可能明晰。惟其如此,程序才更容易懂,因為這是正常人最基本的認(rèn)知世界的方式。
? ? ? ??對時序影響很大的一個因素是并行,并行的一個常見實(shí)現(xiàn)方法是啟用多線程。多線程程序之所以難寫,不在于線程本身的機(jī)制或同步多么難以掌握,而在于并發(fā)使整個程序中的邏輯變的更加復(fù)雜。
? ? ??最后做一點(diǎn)總結(jié):軟件是固化的思維,其基本組成是概念和邏輯。
總結(jié)
- 上一篇: Ibatis中的大于、小于、like等符
- 下一篇: Commons Collections学