- 簡單之美:軟件開發實踐者的思考
- 倪健
- 4472字
- 2018-12-31 18:20:50
1.2 本質的把握
把握軟件和軟件開發的本質,可以使知識和技能的積累變得更加高效,而把握認知方法的本質,可以使知識和技能的積累總是走在正確的道路上。
什么是軟件的本質?在前一節中,我給出了自己對于軟件本質的理解,那就是二進制和與或非邏輯。
我不認為二進制和與或非邏輯是對軟件本質的唯一解釋,事實上,每個人對軟件的本質都有著自己的理解。人們在自己的思想長廊中往前追溯,然后會在一個地方停下來。他們認為,在這個地方,一切都是常識性的知識,雖然可以繼續分解和往上追溯,但是已經沒有必要。我把這種狀態下對軟件的認識稱作軟件的本質。
而軟件開發的本質是什么呢?
軟件開發是一項具有藝術性的科學工作。一方面,因為軟件是邏輯學和數學的應用,所以軟件開發是科學性的工作;另一方面,因為軟件的實現有無限種結構形式,而且每一種結構形式都富含人類的創造和想象,所以軟件開發是藝術性的工作。
有些人還可能會從心理學和管理學角度來闡釋軟件開發的本質。我不贊同這個觀點,但這不是重點。
重點是什么呢?
重點是我們需要形成一個自己的、系統而且完整的觀念。這種觀念,一定會與你所有的認知融合在一起。它來自經驗和實踐,反復驗證之后會成為你思想的一部分。很顯然,要排斥一種觀念是容易的。可是,沒有自己的思想體系,就更加容易陷入一種迷惘的狀態。
如果你嘗試建立有體系的觀念,你會用自己的觀念解釋一切,你也會不斷地在失敗中修正觀念,那么你最終會在自己觀念的帶領下走向成功。舉個例子,在現實世界中,蘋果會從樹上掉下來,你不會懷疑這一點,這就是你的世界觀的一部分。可是,在微觀世界里,你的觀念會遭到重大打擊。你需要調整世界觀,用更復雜的方法來解釋世界。你不斷調整,最終得到真諦。這種有體系的觀念,我稱作思想體系。
思想體系的建立是很有用的。我們不妨以學習為例。你知道嗎?最有效的學習方法就是用自己的思想體系來接納外部知識。這也可以說明一個問題,你看,在計算機書店,有很多大師級的作品,他們的知識向所有人開放,可是很多人從中得到的收獲總是非常有限的,為什么?因為思想體系還沒有建立,很多人還無法對書中的知識進行有意識地提煉和抽象,所以總是會有很多疑惑和不解。
其實,只要經過足夠長的時間,每一位軟件開發人員都會不自覺地形成自己的軟件開發思想,這和過日子是一樣的。
不過,有很大一部分軟件開發人員在經歷短暫的思想積累以后,卻偏離了軟件開發的方向。很多軟件開發人員,熱衷于轉向另一個更加不成熟的領域——軟件開發管理。糟糕的是,這些不成熟的軟件開發管理人員,在不自覺中為其他軟件開發人員設置了更多通向成熟的障礙,最終破壞了軟件開發的整體環境。
在以后的章節中,我們會詳細討論與軟件開發管理相關的問題。這里我想先簡單表達一個觀點——管理,其實是軟件開發中的輔助性工作,它很重要,但不是必需的。好的管理是高效的燃油添加劑,但是,我已經看過太多糟糕的管理,它們對軟件開發的負面影響遠大于軟件開發人員自身。
軟件開發思想難以形成體系,除了浮躁和放棄,還有一個原因。
在我們這個時代,很多軟件開發人員都比較年輕,他們正在進入一個眼花繚亂的世界。與二十年前的軟件開發人員相比,他們面臨著更多的選擇。而要想做出正確的選擇,需要時刻保持清醒的認識和精準的判斷。在軟件領域中,充滿了豐富的創造成果和層出不窮的新概念,毫無目標的追逐會使有限的積累能力稀釋,從而使知識和技能的提升變得低效,甚至走向錯誤的道路上。
我在軟件開發生涯中同樣走了很多彎路。比方說,我曾經如饑似渴地閱讀了大量自己不太理解的軟件書籍,可是收效甚微。當我回頭反思自己的軟件開發生涯時,一方面認識到自己不是一個具有軟件開發天賦的人,另一方面也為自己沒有幸運地得到正確的指點而深感遺憾。哪方面的指點呢?不是如何使用某一款開發工具,也不是如何實現某一個精妙的算法,而是積累知識和技能的方法。
方法是我們一生中最有價值的知識財富。
談到這里,我想到一個有趣的社會現象。
很多軟件開發人員都接受了4年的大學高等教育,但是他們中的大多數人并不為自己在這期間取得的成績而驕傲,有些人甚至還抱怨自己沒有學到任何有用的知識。這種認識是不夠全面和客觀的。其實,我們在這4年里學到了最重要的知識——做人和做事的方法。在那段時間里,我們開始獨立生活和思考,開始與一些和自己的成長環境不同、但知識和思想層次與自己接近的年輕人互相接觸和相互影響,開始獨立地為自己的生活和學習做決策等。與這些相比,學科內容本身并不是那么重要。
總之,如果思想體系沒有建立,找不到建立思想體系的方法,以及不會應用思想體系來解決問題,我們就無法把握事物的本質。
在進入企業應用領域的這些年,我接觸了很多新的概念:包括客戶端、服務端、Web服務器、應用服務器、服務端容器、應用框架、遠程方法調用、WebService、SOA、ESB、BPMS
等。每個概念都有數量龐大的衍生內容。對于新進入這個領域的開發人員來說,一下子面對這么多的概念會有點無所適從。
按照我們前面的說法,建立一個思想體系是最重要的。也就是說,只有在一個完整的上下文中思考才能真正解決問題。所以,我嘗試用一條線索把上面的概念串聯起來。
在1.1節中,我們提到了編程語言的發展。編程語言是軟件開發必須使用的計算工具。在企業應用中,計算工具仍然是這些編程語言,只是計算的平臺被推廣到了網絡上。
很多計算機連接在一起組成一個網絡。連接的含義是指,計算機之間可以進行開關信號的傳遞(有線或者無線),為了保證連接和那些開關信號是有意義的,業界制定了一些標準協議。例如,TCP/IP協議。若想了解網絡協議,可以參考相關的書籍。
在企業應用中,網絡連接很重要,一方面是因為它能滿足基本的信息傳遞的需求,另一方面還可以通過網絡連接來使用其他計算機的計算能力。計算機的價格與計算能力通常存在一個指數關系,所以企業必須充分使用那些昂貴的計算能力。
提供計算能力的計算機就是服務器,而請求利用這些計算能力的計算機就是客戶端。
我不認為軟件開發人員充分認識了這一點。當系統面臨著計算性能問題時候,很多軟件開發組織甚至還沒有意識到分布計算的重要性。
如何利用服務器的計算能力呢?有很多種方式。這些年,業界最流行的是Web服務模式。在這種服務模式中,客戶端變成了瀏覽器(甚至屏蔽了計算機的概念),服務端則是遵循Web協議的任意實現。換句話說,采用這種服務模式的企業應用,只是借用了Web服務與客戶端交互,位于延伸空間中的各種概念與創造并不依賴于Web服務。
通常情況下,應用服務器是Web服務器之后的第一個延伸。Web服務器對客戶端請求信息(URL)進行分揀,具有指定特征的信息交由應用服務器來處理。
為什么需要應用服務器,而不是直接面對應用程序?這是因為很多有價值的公共任務需要應用服務器來處理。以JavaEE應用服務器為例,應用服務器負責建立一個企業應用程序空間,把JSP頁面編譯成Servlet,管理服務線程,維護各種寄居于容器中的組件生命周期,提供事務服務、安全服務和消息服務,還有像配置管理、外部資源連接、數據庫連接池等。應用服務器的作用是很大的。
我們提到了服務端容器,這又是個有趣的概念。我們知道,為了使用應用服務器提供的各項服務,你必須按照容器定義的接口來開發組件。這些組件往往無法獨立存在,甚至連生命周期也掌握在容器的手中。這有點類似于回調函數,但是比回調函數的想象豐富多了。
很多軟件開發人員毫無節制地開發容器組件,程序中到處散布著和容器相關的參數。這種做法是不對的。盡管容器提供了豐富的功能,但仍然要盡量使應用程序和容器隔離,經過這樣隔離的應用程序才具有良好的移植性。實際上,應用程序應該與任何第三方的框架和平臺隔離。
對于企業應用來說,有了應用服務器和服務端容器還不夠,有很多第三方的應用框架對應用服務器的功能做了一些補充。例如,Struts使用MVC模式為頁面與后臺應用之間建立了一種新的聯系方式,Spring提供了一個輕量級的容器實現等。這些第三方應用框架中的優點正在被緩慢地引入到應用服務器的標準中。
為了更好地使用服務端的計算能力,我們要用到服務端的分布式計算。事實上,應用服務器早就支持了這種計算模式。服務端的分布式計算是高性能企業應用的基礎,而遠程方法調用則是分布式計算的基礎。
遠程方法調用使分布式應用與單機應用從程序代碼這個級別看上去變得沒有什么不同。當然,遠程方法調用有一些額外的工作要做,例如,對于RMI(Remote Method Invocation,遠程方法調用)來說,需要使用RMI注冊服務器來獲取遠程方法的引用。
RMI的問題在于,首先它是Java特有的(雖然可以與其他語言進行映射);其次它使用了特定的服務協議。于是,業界提出了WebService的概念。這使遠程方法調用被提到一個新的高度。與RMI這類的實現截然相反,WebService獨立于任何平臺。它可以附加在HTTP這類最普遍使用的協議上,完成異構平臺間程序代碼級別的整合。
在Web Service出現的頭幾年,業界并沒有找到使用它的最佳場景。直到某一天,它悄然成為SOA的一塊重要基石。
我們正處在SOA概念泛濫的年代,有些人擁抱它,有些人排斥它。其實SOA一點也不神秘,它只是遠程方法調用的變體。不過,這種變體是革命性的,它改變的不僅僅是一種技術實現,它改變的是構架企業應用軟件的思想。
為什么呢?
企業應用軟件傳統的構建方法是,首先進行數據或對象建模,然后基于這些模型來完成業務功能。這個過程不是一次就能成功的。
因此,在分析和實現業務功能的時候,要時時對數據或對象模型進行修改。修改的工作比較煩人,涉及大量遺留的應用。MDA希望完成模型到業務功能的自動化,從而盡量減少煩人的修訂工作。
當然,傳統的構建方法也不是刻板的,在數據或對象建模前,通常會盡早地使用用例來描述業務功能。即便如此,傳統方法的首要目標仍然是數據或對象模型。
而與傳統方法不同,SOA面向服務來建模。它更偏重于用例中的行為,而不是實體。之所以關注行為,是因為SOA有一項特殊的使命,那就是整合企業中的所有應用,包括新規劃的系統和已有的系統。
對于已有的系統(軟件資產),考慮數據和對象模型意義不大,考慮如何利用已有系統的功能才是關鍵。所以,如何快速有效地抽取已有系統的功能,是首先要考慮的事情。
由于WebService的發展和普及,抽取功能已經是一件很容易的事情了。這為SOA的推廣鋪平了道路。
對于新規劃的系統,使用傳統構建方法更好。很多軟件開發組織,總在追尋解決問題的銀彈。其實,沒有打中目標,通常不是弓箭不好,而是你還沒有掌握使用弓箭的技能。
因為SOA的普及,ESB也變得引人注目。注意到了SOA的特殊使命了嗎?企業服務總線就是用來整合企業的所有應用的,它支持異構的系統在一個共同的契約下發生關系。就這么簡單。
與之類似,BPMS也應運而生。SOA確立了整合系統的思想,ESB提供了準備就緒的服務,業務流程管理系統就是使用這些服務的工具和平臺。
好了,以上就是我對那些概念的思考。
我把那些概念串成了一條線索。現在,線索中的每一個節點,都有了一個合理的解釋。我不認為自己的解釋和線索是唯一的,甚至也許有些還不夠準確。但重要的是,我現在有一個體系來接納新的概念了。
根據以往的經驗,思考新的概念,經過解釋、修正、再解釋,最后把這些新概念轉化成為思想體系的一部分。這應該就是認知方法的本質了。