程式導向程式設計(結構化程式設計)的不足

2020-07-16 10:04:25
結構化程式設計也叫程序導向的程式設計,它和物件導向的程式設計是相對的。

結構化程式設計的基本思想是自頂向下、逐步求精,即將複雜的大問題層層分解為許多簡單的小問題的組合。整個程式被劃分成多個功能模組,不同的模組可以由不同的人員進行開發,只要合作者之間規定好模組之間相互通訊和共同作業的介面即可。

例如,一個大型的網路遊戲可以分成動畫引擎、地圖繪製、人工智慧策略、遊戲角色管理、使用者賬戶管理、網路通訊協定等諸多模組。不同模組可以分別由不同的小組開發,每個模組都要對外提供一個介面(一般就是函數和全域性變數的集合),以便其他模組能夠呼叫自己提供的功能。

例如,人工智慧策略模組可能會提供在地圖上尋找路徑的功能,地圖繪製模組需要提供查詢道路和障礙物、建築物位置的功能,這個功能會被人工智慧策略模組中的尋找路徑子模組呼叫,遊戲人物需要前進時,就會呼叫人工智慧策略模組提供的尋找路徑的函數來決定下一步如何行走。

計算機界最高獎“圖靈獎”得主、Pascal 語言發明人沃斯教授有一個著名的公式,就是:

資料結構 + 演算法 = 程式

這精闢地概括了結構化程式設計的特點。資料結構和變數相對應,演算法和函數相對應,演算法是用來運算元據結構的。

在結構化程式設計中,演算法和資料結構是分離的,沒有直觀的手段能夠說明一個演算法操作了哪些資料結構,一個資料結構又是由哪些演算法來操作的。當資料結構的設計發生變化時,分散在整個程式各處的、所有操作該資料結構的演算法都需要進行修改。

結構化程式設計也沒有提供手段來限制資料結構可被操作的範圍,任何演算法都可以操作任何資料結構,這容易造成演算法由於編寫失誤,對關鍵資料結構進行錯誤的操作而導致程式出現嚴重問題甚至崩潰。

結構化程式設計也稱為程序導向的程式設計。過程是用函數實現的。因此,結構化程式設計歸根到底要考慮的就是如何將整個程式分成一個個函數,哪些函數之間要互相呼叫,以及每個函數內部將如何實現。

此外,結構化程式設計難免要使用一些全域性變數來儲存資料,如一個網路遊戲一般會以一些全域性變數來記錄當前戰場上有多少個玩家,每個角色在地圖上的位置等。這些全域性變數往往會被很多函數存取或修改,如選擇角色前進路徑的函數可能就會需要知道當前地圖上有哪些敵人以及敵人的位置。

在程式規模龐大的情況下,程式中可能有成千上萬個函數、成百上千個全域性變數,要搞清楚函數之間的呼叫關係,以及哪些函數會存取哪些全域性變數,是很麻煩的事情。

下圖所示為結構化程式的模式,Sub 代表一個個函數,箭頭代表“存取”或“呼叫”。


圖:結構化程式的模式