天天看點

軟體即抽象

本文關鍵字:抽象是軟體的本質,設計是程式設計的本質

首先,什麼是程式設計,這或許要先問,什麼是軟體,因為具體程式設計就是一種“在某平台下,使用某語言,針對解決某個需求進行實作,某個問題進行解決,由程式團隊完成最終遞交給客戶并維護的整個過程,産生的結果就叫軟體”,人們隻注意到了作為結果的軟體,但其實這裡提到了很多實體和對象 ----- 整個軟體和軟體開發,它是一種寄涉衆多的人類工程,每一個都不可分别而論。

具體到工業層次的軟體開發和應用上,人們最終追求的始終是如何控制軟體的生産周期,降低成本。更靈活地處理新出現的需求和軟體本身改良的代價 ------ 曆史上存在過的,和發展到現在,我們見過的不同程式設計形式都可以泛性地歸入這個讨論。對于大中型軟體開發,存在著名的關于銀彈問題的讨論。這就是軟體工程和開發的标準定義

那麼,什麼是抽象呢? 抽象,顧名思義,抽象抽象,抽取事物形象的一面, 那麼,為什麼需要抽象呢?首先,計算機科學和程式設計是一門複雜性很高的科學,人腦往往不适于長輻記憶或直接面對複雜的二進制底層,人們在面對根本無法控制的事情時,往往把它們轉化為另外一件可控的事 - 這對于W事W物都是這樣的。其次,從問題到解決不是一步而就的,是以需要建立中間層,先完成這諸多中間層,當中間的邏輯被解決的時候,最終的事情自然就變得簡單了,還有更多,抽象源于一個簡單的事實,把事物從邏輯上分開,這樣就會解偶它們之間的聯系.隻有把接口拉高,向高層抽象,那麼就可以忽視平台邏輯(實際上正是正面繞過),面對一個抽象了的簡單化的結果 比如抽象是曆史上在開發中解決移殖問題最好的方法,而實際上,增加抽象是解決一切程式設計問題的方法!!(by某某牛人)軟體即抽象。抽象是軟體的本質。抽象足可以被稱為“軟體原理”

總之,既然軟體與開發在工程層面源于上面四大件(平台,語言,問題與需求,設計與人),抽象就在軟體的這些各個層面都存在。下面,我們就從大的工程方面,從程式設計的最初形态開始,來講解抽象在這四個層面各有哪些關聯和展現。

1)平台和語言層中的抽象

最初,人們想得到一台能高速模拟數學計算的自動化機器,試想隻要有了這樣一套機器和數學方法,隻要機器的速度足夠快,形式化的問題有解,它就能在人類有意義的等待時間内産生結果,圖靈機的運作原理為自動機理論,它的計算方式被稱為形式計算,形式化了的問題就叫“算法”,圖靈機理論揭示并解決了現代計算機在抽象層次運作的本質即形式計算.這對計算機發展和工業化的意義不言而喻,.這不光是硬體上的,還是軟體上的,

硬體上,出現了馮氏機.馮氏架構将執行指令的CPU和存放程式的記憶體分開,其帶來了可置換軟體的雛形 - 程式機器分離。CPU作為主導,內建了對記憶體的管理,是計算機中的總控制中心,機器運作的過程就表現為通電狀态下的CPU從同樣通電狀态下的主存裡取指令并高速譯碼串序執行的過程.在CPU的眼裡一切都是記憶體位址,指令也是記憶體位址. 可見,這裡CPU不但執行指令,還管理組織資料的事.-------- 這深刻描述馮氏模型的特征和導緻了馮氏程式設計的統一性.馮氏的哲學觀就是資料和操作資料的指令。資料即指令,指令即資料。

軟體上,就是算法。既然在CPU眼裡,一切都是記憶體位址和指令,而且這導緻了馮氏模型的統一性.這些僅僅使機器知道如何尋址和譯碼,至于計算機如何形成任務,它能完成什麼樣的傷務内容呢? 馮氏計算機是如何把問題-這裡是科學計算問題,形式化的呢?最初的人們是如何使用最原始的計算機的呢?------ 這就是CPU級的執行路徑,由資料和指令組成的程式分片斷在"棧式機"裡運作,每個片斷在一個個高速生成-消亡的可執行單元裡進出,占據CPU的時間資源,CPU有機制直接表達這種棧幀 - 它裡面的寄存器,CPU也用科學計算處理單元來完成指令的執行,空間上,CPU用寄存器編址記憶體位址,CPU也支援編址操作記憶體中存儲的整型和浮點型資料,形成最終組成應用和程式的指令序列和資料址位,最終完成程式的執行。------ 這時的計算機應用當然首先是在一些大型主機上作科學計算不能作通用計算。機器是裸機,這時的軟體形式就是一些用彙編寫的應用,最初的軟體就是問題尾端的應用,,開發上,沒有複用,寫程式一切都要從頭開始,程式是離線開發(電傳在另一台同類型機上開發調試),燒錄到ROM的,開發過程就是直接電傳寫裸機上的應用(沒有開發支援和安裝支援)。軟體也不能稱為軟體(我們把出現OS之後軟體稱為軟體)。

總之,這便是最初可程式設計(科學)計算機的基本雛形以及開發和應用的雛形。它是圖靈理論算法的最原始表現形式(算法可以是一切最簡的可形式化,到任何複雜化了的可執行,開發,釋出程式形态,但始終不離圖靈計算本質的那些計算問題,以下會不斷提到)。直到出現真正的軟體系統使之變得現代化,這就是現代OS的出現。

那麼為什麼要出現軟體系統呢?

最初的大主機的處理能力太過于空閑,一個目前使用機器的使用者對于這台機器的處理時間和處理能力是獨占的,機器内沒有管控這些程式該如何更好運作,出錯了怎麼防崩之類的邏輯,而且,不僅機器本身沒有自理能力人力管理和使用機器也麻煩,很多很多年前,那時,會編下的操作員和程式員,要完成先控制機器的任務(機器上有重新開機,暫停等按鈕,在機器内也有相應的控制指令),再使用機器,效率不高也不夠友善。更别說開發了。

于是急需出現一種能代替人管理機器的層面和機器管理程式的層面,将其顯式地整合進一個随着機器存在的層面直接常駐裸機之上,這個層面就是最初的軟體層面,(最初的分時系統,這些層面就逐漸演變為“軟體OS”的原型。此時,它可能并不叫“作業系統”。),再後來,人們自然想到,由于計算機的硬體速度足夠快,為什麼不到所有能想到的,都軟體化整合進這個層面呢?比如為什麼不把程式設計都搬到這個機器和內建到軟體層面來呢?這樣,各行各業使用計算機的人都可以面對一個統一的,大而全的,更強大的軟體層,,普通使用者可以面對一個更強大的功能,PC可以接入更強大的外設,供更多人使用,計算機終于開始像個PC了。對于開發者,進階語言完全也可以實作在軟體層,軟體開發釋出就可也在軟體層更友善進行,程式員可以直接在軟體層實作應用,使用平台上的API,(這裡并沒有一個顯式的OS和進階語言誰先誰後出現的問題,但肯定一前一後緊密,系統和系統開發是一對自然而然的結果和現象,比如OS本身也需要用更好的語言來開發完善,更強大的軟體要求出現更強大的開發手段。。)。。

進階語言系統同樣基于圖靈理論,編譯原理即是這樣一種學科,發明語言本身用的是”圖靈算法“,它為源端的源碼建立一套形式表示,映射為可運作的目标邏輯,并傳給目标運作(這裡的目标即OS執行棧),文法表示和語義映射這樣的問題,是進階語言前端的重要課題,由于是圖靈原理,它要盡量避免二義性,用計算機來識别的語言隻需是(不是隻能,而是隻需)某種形式語言而非我們的自然語言(如果硬要這樣,那反倒是不合理和不必需的,因為自然語言是一種形式語言的超形式,在文法語義層面存在很多歧義,比如一個句子有二層語義,雖然這是現實中一語雙關的美妙使用,但是在程式設計中這正是要極力避免的,僅僅因為不需要那麼做,計算機本來就被設計成隻處理确定性的算法。

在OS層內建進階語言,不管如何,事實上人們也這樣做了,此處略去1W字有了作業系統和進階語言之後的好處 ----- 我們分别着重來說這二者給開發帶來的新的複雜性和便利性,

對于開發,OS層為開發新增了一個平台和基礎抽象的層面。平台上使用進階語言進行開發,釋出,必須遵從和适配OS上的以上服務,調用和處理與此相關的所有抽象,對照原來隻有彙編和硬體平台是直接對應原始的圖靈運算模式的原始形式,它産生的程式本身就成了某種進階的混合算法态--我們暫時把它稱為OS層的功能抽象。如果說OS那些抽象給開發帶來的是功能層面的,那麼,語言給開發帶來的影響更為明顯,它帶來的是映射層面的整個疊加。------ 比起彙編和彙編語言是直接對應機器邏輯和語言機器邏輯一一映射的。用語言進行開發時,它産生的程式本身也是多種複合了的算法态。

a) OS為開發貢獻的新的功能抽象層有:

OS帶來的程式運作棧:OS為軟體準備了一個過程和函數棧,進階語言(我們稍後會講到)的後端連結産生的程式會連結到OS運作可執行體的服務(它們在語言中被作為記憶體配置設定等函數)。

OS層封裝軟硬平台的服務:硬體的特性會被反映到程式設計上,程式設計語言上作為抽象,比如原子操作作為語言關鍵字。平台的并發有時也會成為軟體的直接支援設施。

OS層的API服務:OS為應用準備了一套API,所有語言産生,運作在這個OS上的程式,都可以調用其API服務。

OS層的元件支援:OS上的應用可以以二進制元件複用體的形式出現,進行連結,生成,和運作。

OS也為應用準備一個appmodel,(這個放在領域問題部分來講。)

b) 進階語言疊加了一層映射計算方式作為抽象的疊加參與開發。

首先,進階語言中的類型抽象。

在前面說過馮氏模式就是處理邏輯和資料的,甚至這二者本來就是一個東西,進階語言會有一個類型系統,這裡指的主要是簡元類型系統(UDT,ADT這些擴充語言類型的放在跨越語言的複用部分講),簡元類型模拟了彙編下CPU的類型,而函數定義,過程式流程指令則顯式化了原先無義執行序列中的部分,使之成為有意義的邏輯單元,馮氏開發就二個東西,資料和操作資料的邏輯,到了這裡,類型已經成了一種綜合資料結構抽象和代碼結構抽象的東西(甚至它還綜合了API和接口這些複用的機制。甚至語言的類型系統,OO使擴充語言的庫成為一棵關于類型的大樹。這放在複用部分),這一切都是抽象,讓語言映射呈現出靠人便于使用方面的抽象。

而語言後端與OS運作棧一起,,完成語言系統的根本任務。

可見,OS和語言層為開發引進了抽象的疊加和複雜。是不斷豐富的平台和語言系統給開發帶來的友善性和不友善性産生的新沖突體,它在帶來友善的同時,也帶來了這些複雜性。那為什麼不抛棄它呢,這個問題問得好,問出了抽象的哲學出身:這其實是一對沖突。是抽象的特點。抽象是用更強大的友善性掩蓋和代替相對不那麼重要的友善。

2)超越語言的抽象層,及問題域和人的工程需要給開發疊加的那些抽象層

語言邏輯将到現在為止講到的一切,包括語言本身和平台抽象的部分,都統一于語言服務,或封裝在語言标準庫,或封裝在第三方庫,在計算機看來,都是圖靈原始算法不斷複合,演變的複雜形式和進階形态.最終統一于進階語言開發。

那麼,除了以上OS和語言本身帶來的新的複雜性和抽象層,還有哪些會随着語言進入開發呢?這就是超越語言的抽象層,及問題域和人的工程需要給開發疊加的那些抽象層。它們超越語言,但也可以作為語言服務存在。比如,将加入人類工程和問題抽象的一次性設計,做成架構,這屬于複用部分。

這首先是進階語言時代的算法抽象。

當圖靈能解決數學問題的時候,它實際也能解決這種形式化表達的任何通用問題。試想“1個男人+1個女人=?”這樣的抽象問題如果能得于形式化,在圖靈機眼裡都是可計算的,等價的,跟“1+1=?”一樣,馮氏機自以前彙編時代就有這種能力,之前彙編的算法我們講過,就是根據程式設計上的資料類型(彙編下是CPU的類型)然後按計算機的方法一定套路操作資料形成結果,隻是在彙編時代,開發上沒有讓圖靈算法一次演變到這種複雜形成的可能,那麼現在正是時候,裝配了軟體層面和進階語言的馮氏機就正好可以在程式中抽象這些并映射解決這類的複雜抽象形成新的複合算法。并在軟體和進階語言時代,算法形成了真正自己的學科。

是以算法,它首先也是個數學和科學問題(用計算機作科學計算)。它超越于具體語言語句和類型抽象之上,(因為它是跨越語言的,算法是計算機的學科,不是程式設計的學科),是開發界實作最初抽象,利用計算機原始的解法,建立問題域抽象的手段。

a) 算法層和實作抽象層。

那麼這又是一種什麼樣的抽象開發過程呢?

這裡面的抽象就在于,VS機器和彙編時代CPU類型和操作法,這裡的相當于進階語言中的變量和類型。算法相當于資料結構+資料結構操作。

它将算法用語言的簡元類型來表達成資料類型抽象,進而可以表達成資料結構抽象,然後結合處理這些資料結構的模式,可以提出ADT類型供複用。

但當談到ADT的時候,實際上進入了下一步,跨越具體語言的複用層級了。

b) 語言的接口和複用層,擴充層,繼續抽象層。

厘清語言的實作抽象層和擴充抽象層

在前面不斷提及過語言的複用層,一不小心它就總是和語言的簡元類型和技法重合,進階語言最基本的類型和用法,過程式和簡元類型抽象實際上就是最基礎的可複用設施複用支援。(對類型的抽象就是程式設計設計的馮氏資料抽象思想為中心的開發方式,類型抽象和資料結構是進階語言用語言來解決計算,描述算法的最基礎的工具。而代碼結構就是複用手段,工程手段。是以提出類型本身,它就是一種複用,甚至這是語言用類型來完成語言本身的手段,比如運作時和庫樹),不過也有複雜和顯式的(比如算法科學中,簡元類型可以完成算法,但ADT則是使用者抽象擴充的分水嶺。)。現在我們正式來歸類複用層面給開發增加的新抽象,------ 為什麼複用這麼重要,因為進階語言在映射層能解決的問題所有問題,就是使用算法實作抽象和使用複用連接配接已有實作或第三方抽象,擴充使用者抽象,除了算法,進階語言的複用支援是語言對接人方面工程目需求那層的 -- 接口和複用。它是進階語言能連接配接抽象的第二種手段。

更複雜的接口和複用層有:進階語言習慣用法。tricks,技法,語言的UDT,ADT擴充系統,進階語言的API和二進制複用機制。庫級擴充系統,元件擴充系統。過程範式,等

c) 問題域

在軟體時代,這裡的軟體和軟體開發分系統軟體和系統應用軟體,系統程式設計領域,包括OS的發明,語言的實作本身,都是系統軟體。上面提到的算法和資料結構,就頻頻服務于系統實作與系統應用開發。

問題域為開發引入了什麼新的抽象呢?

首先,一個現代的OS,基本涵蓋了對GUI,graphics,network,socket,持久,io,等領域的基本抽象建立。然後,一個具體APP中,最大的肯定是問題本身所處領域邏輯。

最後,一般OS基本還建立了2個APPMODEL層,一個是console appmodel,一個是gui appmodel,你可以将appmodel了解為程式的模闆,其作用将domainlogic+appmodel形成最終該OS下的一個具體app。

d) 人帶來的新的設計抽象層面。

當考慮到人的需求,它又是一個更進階的,超越語言和問題域的話題,歸納一下,它為現代開發引入的新抽象有:設計模式,比如設計模式,可以在很高層次上,為問題建立一套MVC的架構。

甚至更多的語言,如帶來了腳本語言,更強大的虛拟機語言這樣的課題。和領域語義,如xml, 中間件,更細分的appmodel和問題域抽象,web appmodel,game appmodel這樣的東西。,你可以将它看作為是對前面1)a,b,2)a,b,c的全盤設計,修正,選型,創新,和附加,和全盤颠覆。或部分全部直接采用。

如QT架構庫,它是對CPP語言,平台庫,等等,這四個東西的封裝,修正增強,這裡有鮮明的重設計特征和工程總層面進行開發的痕迹。

3) 總結:軟體和開發的原理和模式-如何建立抽象,給問題模組化,複用(擴充模式)和映射抽象,處理平台抽象

是以,看出來了嗎,軟體和開發的原理和總模式,其實就如何2)中abcd一樣,已經證明是這些抽象不斷疊加或修正的過程呈現。而人類設計,它是對1)a,b,2)a,b,c。的部分全部直接采用。或重設計。最終,通用OS和進階語言如何解決新時代下,解決程式運作和開發的問題,就是解決如上抽象和設計的問題。

比如設計模式,當談到設計是,表明這是一種人類設計。将加入人類工程和問題抽象的一次性設計,做成架構,這屬于進階複用部分,同時又是典型的設計。

這是《程式設計新手真言vol1:程式設計新手抽象與理論》下文我們談設計,程式設計即設計,

(此處不設回複,掃碼到微信參與留言,或直接點選到原文)

軟體即抽象