軟件的本質是什麼?它帶來了什麼?

紫碧落日月心


軟件的本質是什麼?

我將從軟件-軟件設計-編程幾個角度來談軟件的本質和其依託實現的方式。

其實大家根本不必去追求軟件的定義,我認為,軟件的本質就一個解決我們生活生產問題的一個工具,比如我們為了隨時隨地繪畫,就開發了畫圖軟件,為了娛樂,就開發了各種各樣的遊戲等等。與生活中其他工具本質都一樣,例如,我們不能走的很快,就創造了汽車這個代步工具,我們不能飛向太空,就創造了火箭這個工具。只不過軟件這個工具,比其他工具來的更復雜,更龐大。

一切工具都是為了解決人的問題,軟件也不例外。但人類世界的現實問題到軟件的解決方案的實現路徑跨越太大,無法一步躍遷,這就需要設計分解成一系列的躍遷步奏,這就是軟件設計的本質,軟件設計好就需要編程。

而編程的本質就是用編程語言對這一系列過程進行描述。所以編程語言是邏輯的載體和描述工具。

但就像一位大師說的“語言磨礪了我們的思維方式,也決定了我們的思考範圍”,所以不同的編程語言又反過來影響了軟件的定義。比如

從過程來看,軟件 = 數據 + 算法;

從面對對象看,軟件 = 對象 + 控制;

從函數式來看,軟件 = 解釋 + 應用(eval-apply loop);

從邏輯來看,軟件 = 邏輯 + 控制。

各個角度不同,軟件的定義就不同,但是,最終都逃離不過一個定義:解決人們需求的一個工具。

如果要用專業的解釋來說就是:

雖然不同角度對軟件的理解和分解方式不盡相同,但都有異曲同工之處,即軟件分為兩部分:

  • 一部分是數據,不管是叫對象、邏輯還是模型;
  • 一部分是控制,不管是叫算法、解釋還是語義。

這就是軟件的本質:
軟件是數據和控制的有效結合,其中數據部分才是真正有意義的(What),控制部分只是影響數據部分的效率(How)。數據和業務或領域模型有關,無法標準化;但控制是可以標準化的,比如:遍歷數據、查找數據、多線程、併發、異步等,都是可以標準化的。

這裡附上一張我的桌面圖,這些軟件圖標就能夠體現我要使用的軟件工具有哪些。



技術閣


代碼,程序,應用的工具


輝哥講高中數學


隨著互聯網和信息技術的高速發展,各行各業的軟件層出不窮,通過PC端或者手機端辦任何事情都離不開軟件。那麼軟件的本質究竟是什麼呢?下面是我對軟件本質的分析。

軟件是一種固化的思維。其根本組成是概念和邏輯。軟件世界中的一切的故事始於一個機器模型,而這個基本的機器模型並不複雜,甚至可以用三個關鍵概念來概括:指令、數據以及棧。其邏輯也比較簡單,即按照指定的順序,逐步執行各條指令。但也就是這樣一個簡單的模型,支撐起了整個軟件的世界。軟件構建的過程就是從客觀世界中的概念和邏輯向機器模型逐步進行映射的過程。由於編譯器(或解釋器)的存在,最後一重映射已經被無限簡化,因此我們可以認為以編程語言為載體的代碼即是固化後的思維,包含了所有固化後的概念和邏輯。

       為完成這一任務,首先軟件的邊界必須清楚,即“要轉換的究竟是什麼”必須儘可能明確,此即需求開發的根本任務。從需求向最終代碼的映射可以稱為軟件構造。需求開發的結果:規格說明和軟件構造的結果:代碼表述的實質上表述的是相同的東西,所不同的只是視角,表達方法和詳盡程度。需求開發姑且不論,軟件構造即在確定的範圍內打造概念的邊界和定義概念間的邏輯關係的過程。

        打造概念邊界時原則可以有許多,但手段只有一個,即抽象。從本質上講,抽象是一種認清事物本質,並進行歸類的過程。與抽象相對的是具體,但抽象的來源也是具體。假使我們需要對【人】這一名詞進行定義,那麼必然是要從張三,李四等等具體的人身上抽取共通特徵,而後才能完成定義。最終結果是【人】這一概念來源於張三,李四,但又不是張三李四。這樣一個從具體的事物中抽取共性,再進行命名的過程就是抽象。

        我們常說的功能分解(Function Decomposition),抽象數據類型(ADT),面向對象(OO)都可以看做是對事物進行抽象的具體方法。但不管使用什麼樣的方法,打造概念邊界通常並不容易。這種困難起源於概念本身的邊界並不清楚,存在模糊性。比如:當我們描述一本書的時候,那麼這本書是否被借出了這種信息,是既可以作為書的基本信息的一部分,也可以通過查閱借閱人的信息來存儲的。對此,哲學上的表述是:世上萬物是運動的,聯繫的,而非靜止的,孤立的。

       更困難的是一旦切換視角,相同的概念又可以有多種劃分方法。好比說,我們可以很容易界定什麼是人,什麼是猿,但當我們試圖把人猿歸類的時候就依據我們的視角進行抉擇。因為它似乎是人,似乎是猿,卻又更是人猿。打造概念邊界時正是類似人猿這類概念讓我們犯難。有些問題甚至只有選擇而沒有答案。莊子對這種事情的觀點是:自其異者視之,肝膽楚越也;自其同者視之,萬物皆一也 。

       也正因此編程是一種實踐多於是一種理論。

        我們可以抽象出一些指導性原則,比如開閉原則,比如里氏代換,比如高內聚低耦合,但一旦面對現實時卻只能具體問題具體分析。也許有人認為這裡所說的澄清概念邊界專屬於面向對象,其實不是。當你決定某一組函數專門負責文件操作時,你同樣是定義了【文件操作】這樣一個概念的邊界。包,類,模塊,數據結構,方法等等這些名詞都可以對應到一個個具體的概念,是抽象這一工作的結果。

       我們把概念之間的關係定義為邏輯。而概念間的邏輯關係可以被分為兩類:一類是概念所固有的,基本不受具體應用影響的靜態關係。比如:人是比老師或學生更為泛化的概念,老師或學生都需要有一個名字。這就是我們常說的繼承,包含聚合(整體與局部)等。需要特別一提的是框架(或設計模式)更多的體現的是一種靜態關聯關係。框架把全局性,共通的部分抽象出來,固定在框架之中,把局部的,需要定製的東西開放給用戶,來應對變化。與這種靜態的邏輯關係相比,具體化的概念之間的動態關係顯的更為繁雜。如果說概念間的靜態關係體現的是一種預先存在的必然關聯的話,那麼概念間的動態關係體現的則是實現具體功能時體現出來的偶然關聯關係。假設說我們要做一個簡單的監控系統。那麼大致會衍生出下面幾個方面的概念(模塊):

1 照相機:負責拍照

2 圖像處理:負責分析照片中是否有異常

3 數據庫:用於存儲過往的記錄

4 報告功能:一旦發現異常,對相關人等進行通知

5 控制器:根據既定的處理流程,使程序動起來。

6 ... ... 這個時候,控制器和照相機(或數據庫間)的關聯則是一種偶然關聯,是動態關聯關係。把照相機替換為攝像頭也無不可。

對照實現來說的話,照相機的實例可以通過控制器的接口傳入,也可以在控制器的方法中創建,但如果把照相機作為控制器成員,則和這些概念間既有的關聯關係向背離,耦合度會有不必要的增加。

        在動態關係中第一重要的是動作的時序,即先後順序。

       時空的特徵決定了這世界上大多的事情皆有因果,也決定了程序中凡事必有先後。當我們明確了先做什麼,再做什麼,最後做什麼之後,我們才能對事情真正有所把握。不管採用什麼設計方法,都要讓這類路線儘可能明晰。惟其如此,程序才更容易懂,因為這是正常人最基本的認知世界的方式。

        對時序影響很大的一個因素是並行,並行的一個常見實現方法是啟用多線程。多線程程序之所以難寫,不在於線程本身的機制或同步多麼難以掌握,而在於併發使整個程序中的邏輯變的更加複雜。

      最後做一點總結:軟件是固化的思維,其基本組成是概念和邏輯。





分享到:


相關文章: