1. 程式人生 > 實用技巧 >對軟體工程的思考——以menu專案為例進行分析

對軟體工程的思考——以menu專案為例進行分析

前言

在這次的學習中,孟寧老師以一個menu為例,教學了在實際工程中,有哪些地方會用到軟體工程這門學科。也與未來工作接軌,讓我們在編寫程式碼時,要注意將其工程化,為未來工作打下良好的基礎。

1.規範化的頭部註釋

當我們開始一個專案時,最先看到的就是頭部註釋,頭部註釋可以幫助我們更好的瞭解這一部分的程式碼。以menu.c為例

在這裡我們可以看到,編寫這段程式碼的老師——孟寧老師,然後它是用C來編寫的,編寫時間是在2014/8/31,其作用就是完成menu模組。

在實際工作、程式設計中,我們可以對這些頭部註釋進行擴充套件,這樣使得自己的程式碼更易讀,加快合作開發的進度。

2.程式碼的模組化

顧名思義,就是讓程式碼變成一個個獨立的模組,將資料結構和操作放在獨立的原始碼中,這樣每一個模組都將只有一個單一的功能目標,每一個模組也更容易被人理解。同時,如果發生bug,那麼bug只會侷限在很小的模組內,影響範圍也會很小,使得軟體更容易定位bug、更容易維護。

該專案主要有下面幾個主要的c檔案:test.c、linktable.c、menu.c等。開啟各個c檔案後不難發現。我們可以看出在linktable.c中我們都是對資料進行直接操作,在menu.c中是在進行邏輯層的操作,最後test.c則是通過測試,將執行結果展示給使用者。

當代碼模組化之後,就需要介面來實現模組之間的相互呼叫。

3.介面規範化以及可重用介面

介面規格是軟體系統的開發者正確使用一個軟體模組需要知道的所有資訊,那麼這個軟體模組的介面規格定義就必須清晰明確地說明正確使用本軟體模組的資訊。一般來說,介面規格包含五個基本要素:

  • 介面的目的;
  • 介面使用前所需要滿足的條件,一般稱為前置條件或假定條件;
  • 使用介面的雙方遵守的協議規範;
  • 介面使用之後的效果,一般稱為後置條件;
  • 介面所隱含的質量屬性

我們回到menu程式碼中,在.h檔案中進行函式宣告,在.c檔案中進行具體的函式實現。其實就是也就意味著,在.h檔案中,暴露出來的就是我們所需要的介面,以menu.h為例:

這裡有三個函式,即三個介面

  • SetPrompt——設定輸入提示
  • MenuConfig——將命令列加入到選單中,然後執行
  • ExecuteMenu——執行選單引擎

對於其他.c檔案而言,只能呼叫這三個介面,至於其他的函式則是menu.c的內部函式,是不可見的。

而可重用介面,則是其他程式設計師在重用這個介面時應該不需要了解這個介面內部程式碼的組織方式,只需要瞭解呼叫介面和生成的目標檔案,就可以方便的將介面整合到自己的軟體中。4

4.執行緒安全

什麼事執行緒安全呢?

在孟老師的課件中是這麼說的:

如果程式碼的程序中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段程式碼。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。
執行緒安全問題都是由全域性變數及靜態變數引起的。若每個執行緒中對全域性變數、靜態變數只有讀操作,而無寫操作,一般來說,這個全域性變數是執行緒安全的;
若有多個執行緒同時執行讀寫操作,一般都需要考慮執行緒同步,否則就可能影響執行緒安全。

我們以原始碼為例

struct LinkTable
{
    tLinkTableNode *pHead;
    tLinkTableNode *pTail;
    int            SumOfNode;
    pthread_mutex_t mutex;

};


/*
 * Create a LinkTable
 */
tLinkTable * CreateLinkTable()
{
    tLinkTable * pLinkTable = (tLinkTable *)malloc(sizeof(tLinkTable));
    if(pLinkTable == NULL)
    {
        return NULL;
    }
    pLinkTable->pHead = NULL;
    pLinkTable->pTail = NULL;
    pLinkTable->SumOfNode = 0;
    pthread_mutex_init(&(pLinkTable->mutex), NULL);
    return pLinkTable;
}

/*
 * Delete a LinkTable
 */
int DeleteLinkTable(tLinkTable *pLinkTable)
{
    if(pLinkTable == NULL)
    {
        return FAILURE;
    }
    while(pLinkTable->pHead != NULL)
    {
        tLinkTableNode * p = pLinkTable->pHead;
        pthread_mutex_lock(&(pLinkTable->mutex));
        pLinkTable->pHead = pLinkTable->pHead->pNext;
        pLinkTable->SumOfNode -= 1 ;
        pthread_mutex_unlock(&(pLinkTable->mutex));
        free(p);
    }
    pLinkTable->pHead = NULL;
    pLinkTable->pTail = NULL;
    pLinkTable->SumOfNode = 0;
    pthread_mutex_destroy(&(pLinkTable->mutex));
    free(pLinkTable);
    return SUCCESS;        
}

我們可以看出

pthread_mutex_t mutex;
pthread_mutex_lock(&(pLinkTable->mutex));
pthread_mutex_unlock(&(pLinkTable->mutex));

這裡其實就是為了維護執行緒安全,所作出的補充,通過鎖來確保,每次只有一個執行緒可以執行。

結束語

軟體工程是一門學問,絕不是通過這次學習就能完全掌握的,需要我們在實踐中不斷學習才能夠掌握。這樣在未來工作中,才不會出現重大失誤!

補充:

1.環境配置

  1. 在vscode中安裝C/C++擴充套件外掛
  2. 下載MinGW-w64/GCC編譯器,並安裝,然後配置環境引數,完成後在命令列中輸入引數gcc -v和gdb -v
  3. 在我們的專案中配置vscode檔案,生成launch.json和tasks.json
  4. 將標頭檔案加入到tasks.json中的"args"引數下
  5. 編譯執行含有main()函式的.c檔案

2.參考文獻

  1. https://gitee.com/mengning997/se/blob/master/README.md#程式碼中的軟體工程
  2. https://github.com/mengning/menu