麻雀雖小,五臟俱全——由C語言小程序深入學習軟件工程和設計開發(fā)規(guī)范

蘇思暢 - 原創(chuàng)作品轉(zhuǎn)載請注明出處 - 《軟件工程(C編碼實踐篇)》MOOC課程
http://mooc.study.163.com/course/USTC-1000002006

一、課程認識和學習心得

2017年春天,我有幸選修了孟寧老師主講的高級軟件工程課程。這門課從一開始就讓我感受到了不一樣的氣息:線上學習和線下交流同步進行;由學生交流而不是老師講課為主導的課堂;通過循序漸進的在線編程實驗不斷引入開發(fā)設計中的規(guī)范和理念。這些與我之前接觸過的課程內(nèi)容有著極大的差異,它們無不讓我獲得了一種新鮮感。
在線上部分的MOOC課程中,整個學期的教學內(nèi)容通過一個看似簡單的C語言Menu小程序前后貫通,通過不斷地對之前已經(jīng)寫就的代碼進行迭代,我們在為期七周的課程周期里學習了C語言編碼規(guī)范、模塊化通用化的結(jié)構(gòu)設計、回調(diào)函數(shù)的合理使用、面向接口的程序設計等知識點,并進行了充分的實踐。可以說,麻雀雖小五臟俱全,盡管這是一個只有三四個文件、數(shù)百行代碼組成的小程序,但是其中蘊含的軟件工程思想?yún)s與市面上成功的大項目大系統(tǒng)別無二致。
在線下部分的課程實驗中,我們通過使用Go語言實現(xiàn)線上實驗的內(nèi)容,來初窺這門之前未曾接觸過的語言的魅力。同時,也讓我們能夠拋開語言的束縛,將學到的代碼設計思想貫通到其他語言的開發(fā)中去。
而在每周課堂上的日常交流中,我們以Google的軟件工程過程為主題,分享交流了這家公司在實際生產(chǎn)工作中的實踐規(guī)律,以了解軟件工程理論在實際工作中的作用和影響。
可以說,這門課程的學習時間雖然短暫,但它傳授給我的知識卻讓我終身受用。《資治通鑒》中有云:”夫事未有不生于微而成于著“,任何大項目都是從小程序開始積累的,只有在今日通過小程序深入了解了軟件工程的理論,才能在日后創(chuàng)造大項目的成功。

二、線上實驗總結(jié)

在為其七周的線上實驗中,我一共進行了六次在線編程練習,并撰寫了實驗報告。在這里我將對所有的實驗內(nèi)容進行簡要的總結(jié)。至于所有的實驗成果,可以使用以下鏈接來進行訪問和查閱。

http://git.shiyanlou.com/susc/shiyanlou_cs122

實驗一:寫一個Hello World小程序
第一次實驗會讓你初步了解Linux下的一些基本的操作,尤其是使用gcc進行C語言程序開發(fā)的操作。此外在提交代碼時需要進行基本的git操作,在撰寫實驗報告時建議使用Markdown語法來進行書寫。這些能為之后的開發(fā)實踐打下良好的基礎。

實驗二:命令行菜單小程序 v1.0
本次實驗是后續(xù)實驗的基礎,之后的所有實驗內(nèi)容都要在本實驗所做的菜單小程序基礎上進行迭代。本次實驗從功能實現(xiàn)上難度不大,建議在開發(fā)時養(yǎng)成良好的代碼編寫習慣,注意代碼風格。

實驗三:內(nèi)部模塊化的命令行菜單小程序 v2.0
本次實驗要求對之前的程序進行模塊化升級。過去在使用Java等面向?qū)ο笳Z言時可以比較輕松地使用類來進行模塊化設計,但在C語言中尚沒有這么設計的經(jīng)驗。通過這次實驗,可以學習到如何使用鏈表和函數(shù)指針來進行模塊化設計,建立統(tǒng)一的調(diào)用接口。

實驗四:用可重用鏈表模塊來實現(xiàn)命令行菜單小程序 v2.5
本次實驗在上次已經(jīng)用鏈表實現(xiàn)模塊化的基礎之上,進一步將鏈表設計為可重用的模塊。這就要求引入一些類似于面向?qū)ο笳Z言中接口的概念了。接口定義了鏈表的基本操作,如添加刪除和查找,而這些操作都與具體的業(yè)務邏輯無關(guān)。在需要使用鏈表時,才會將我們具體的功能函數(shù)放到鏈表之中,這樣就使得鏈表更為通用,今日的工作可以為之后的實踐提供便利。

實驗五:用Callback增強鏈表模塊來實現(xiàn)命令行菜單小程序 v2.8
回調(diào)函數(shù)(Callback)可以讓下層代碼使用上層代碼,使得具體的功能細節(jié)可以延遲到上層代碼運行是再做決定。同時,由于下層代碼大多需要考慮通用性,不能引入具體的業(yè)務邏輯,回調(diào)函數(shù)正是一種延遲實現(xiàn)、讓業(yè)務與結(jié)構(gòu)分離的優(yōu)秀方法。

實驗七:將菜單小程序設計為可重用子系統(tǒng)
在通過之前的實驗將我們以鏈表模塊為基礎的菜單小程序?qū)崿F(xiàn)出來之后,我們便可以將其中的核心部分進行進一步的抽取,形成可重用的菜單小程序。使用者可以利用我們提供的接口,來進一步擴展菜單程序的功能,并將新編寫的函數(shù)非常便捷地加入到菜單列表中。此外,本次實驗還嘗試引入了帶參數(shù)的功能實現(xiàn),以應對更多樣的需求。

三、課程內(nèi)容學習總結(jié)

通過了這門課程的完整學習,我對于軟件工程和代碼開發(fā)規(guī)范方面有了以下幾點心得認識。

  • 養(yǎng)成良好的代碼風格
    課程上提供的視頻和文本資料詳細闡述了代碼開發(fā)時縮進、命名、注釋等風格規(guī)范,對我產(chǎn)生了重大的影響。以前我也知道代碼風格的重要性,卻沒有去認真了解一般規(guī)范是怎樣的,只是按照書本樣例或者IDE自動對齊來進行。經(jīng)過老師點撥,我認真總結(jié)了實用的代碼編寫規(guī)范,并了解了采用這些規(guī)范的理由。現(xiàn)在我的代碼風格非常優(yōu)雅,學習的內(nèi)容讓我獲益匪淺。

  • 基本的模塊化設計理念
    這里列出的是代碼設計中的一些常見方法:
    KISS(keep it simple & stupid)要求一個函數(shù)或一個方法,只做一件事。擴展開來,在設計上,一個系統(tǒng)、一個子系統(tǒng)、一個模塊、一個類等也只做一件事。
    Using design to frame thecode(matching design with implementation)希望including pseuducode,在從設計到實現(xiàn)的過程中加入偽代碼要好于直接將設計翻譯成代碼。
    不要和陌生人說話原則(Law of Demeter)要求一個對象應當對其他對象有盡可能少的了解。
    學會合理利用控制結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu)來簡化代碼。
    Debug版本中所有的參數(shù)都要驗證是否正確;Release版本中從外部(用戶或別的模塊)傳遞進來的參數(shù)要驗證正確性。

  • 設計可重用的模塊
    模塊設計要求達到高內(nèi)聚低耦合的目標,方便重復使用。接口設計要體現(xiàn)通用性。
    常見接口設計規(guī)范有:參數(shù)化上下文,生死相依原則,移除前置條件,簡化后置條件等,另外還需編寫開發(fā)者指南,供用戶閱讀使用。
    這里要考慮一個接口通用的問題,并不是越通用越好,因為過于通用需要考慮很多情況,導致模塊臃腫、效率低下,因此應該not too specific, not too general。

  • 函數(shù)可重入性和線程安全的考慮
    可重入函數(shù)指可以由多于一個任務并發(fā)使用,而不必擔心數(shù)據(jù)錯誤的函數(shù)。相反,不可重入(non-reentrant)函數(shù)不能由超過一個任務所共享,除非能確保函數(shù)的互斥(或者使用信號量,或者在代碼的關(guān)鍵部分禁用中斷)。可重入函數(shù)可以在任意時刻被中斷,稍后再繼續(xù)運行,不會丟失數(shù)據(jù)。可重入函數(shù)要么使用本地變量,要么在使用全局變量時保護自己的數(shù)據(jù)。
    線程安全指如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結(jié)果和單線程運行的結(jié)果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。
    函數(shù)的可重入性與線程安全之間存在以下的關(guān)系:可重入的函數(shù)不一定是線程安全的;不可重入的函數(shù)一定不是線程安全的;可重入的函數(shù)在多個線程中并發(fā)使用時是線程安全的,但不同的可重入函數(shù)(共享全局變量及靜態(tài)變量)在多個線程中并發(fā)使用時會有線程安全問題(可能是線程安全的也可能不是線程安全的)。

四、寫在最后

本課程的授課以其新穎的形式和內(nèi)容的實用性對于我們之后的實習和工作都有很大的幫助。非常感謝孟寧老師的教導和與其他參與課程同學們的交流,這些都讓我獲益匪淺。由于課程只有短短七周,使得實踐內(nèi)容只能局限在一個C語言小程序的格局之內(nèi),很多的軟件工程開發(fā)理念還沒能夠來得及去接觸和好好消化,這不得不說是一種遺憾。想要彌補這一遺憾,可能要在未來的開發(fā)實踐中自己去慢慢琢磨,細細品味了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容