我的博客 結對項目

Jaein&&Lee結對項目程序員


 

 

合做編程剪影正則表達式

我=。=在實現功能模塊的封裝,而jaein 在進行UI的設計(^.^)算法

軟工這周的項目又告一段落啦~ 在此對個人Partner ---> jaein表示深深的感謝!感謝她在這一週的時間裏,督促我,理解我,同時也能包容我。express

 

結對編程收穫編程

結對編程收穫頗多,歸納起來有以下三點:ide

  1. 以前的我的項目的進度都由本身來控制,有必定的隨意性,而在結對編程中兩我的要相互配合,互相幫助,互相督促,因此項目進度的控制則更加的規範合理。
  2. 以前的我的項目老是認爲能實現基本功能,能按時完成就好,在結對項目中發現,你的馬虎,你的懈怠是對你的隊友的不負責,你只有選擇更好!
  3. 在結對編程中,一味地執拗己見,專斷專行會讓大家的項目根本進行不下去,更多的是須要兩我的的溝通與交流,並且在一方陳述想法時,另外一方要善於傾聽,這樣才能達到更好的效果。

 

結對編程不足函數

結對編程的缺點主要是以下的一個方面:測試

  在代碼風格不一樣這一問題互不相讓,發生矛盾,進而影響工做情緒。優化

 

隊友優勢編碼

  1. jaein很是耐心,在編程過程當中,個人注意力有時候會不能集中,而她老是耐心地提醒我,讓我繼續投入到編程中。
  2. jaein的想法老是很是新穎,對於軟件的界面設計有本身獨特的思考,這一點我自愧不如,因此項目的UI所有由jaein來實現,而最後的效果也出奇的好。
  3. jaein對於軟件的質量要求嚴格,對我如此,對本身的部分更是如此,爲了設計更好地界面,她花費了大量時間來蒐集資料,思考以及嘗試,這種追求完美的心態我也自愧不如。
  4. jaein的國語很棒,跟她合做編程感受溝通徹底沒有障礙,並且我也很佩服她能把多種語言說的很是流暢,(Ps.自愧不如++;  (=_='')

隊友不足

  她有時候會陷入莫名其妙的糾結當中,而在我看來這些糾結是徹底沒有必要的... (=.=)

 

設計方法

  Information Hiding, interface design, loose coupling

Information Hiding這一設計思想體如今以下幾個方面:

  1. 一個重要的方面體如今類的封裝以及接口的設計。即對用戶僅僅暴露出對外的接口,而具體的實現細節對於用戶來講是不可見的,即在多層設計的層與層之間加入接口層,以及在全部類與類之間都經過接口類來訪問。
  2. 另外一個重要的方面體如今類的全部數據成員都是private,全部的訪問都須要經過訪問函數來實現。

Interface design主要體如今計算模塊與界面模塊的交互上面

  考慮到效率的緣故,咱們的軟件核心的計算功能是用C實現的,而界面是用C#實現的,將核心的計算功能封裝成DLL,而且在界面模塊中調用相應的計算功能。針對這個項目設計了以下的6個接口:

    1. public extern static IntPtr generateExpression();
    2. public extern static IntPtr calculateExp(string inputstr);
    3. public extern static void setting(int OperatorNum, int Range, int ExcNum, int MuldivOrNot, int BracketsOrNot, int NegOrNot, int FractOrNot);
    4. public extern static int judgeNegInCalculate(string expression);
    5. public extern static int judgeDivideByZeroInCalculate(string expression);
    6. public extern static void problemForOutFile(string ExcOutFile, string AnsOutFile);

interface design主要爲接口設計

各個接口含義以下:

  1. 隨機生成一個四則運算表達式,返回表達式指針,而且經過Marshal.PtrToStringAnsi(generateExpression());轉換爲字符串。
  2. 給定一個合法的四則運算表達式計算值,而且返回結果指針,經過Marshal.PtrToStringAnsi( calculateExp(expression));轉換爲字符串。
  3. 指定所要生成四則運算表達式的各項參數,OperatorNum指定運算符個數上限,Range指定表達式中「數」的上限,ExcNum指定生成題目的數量(用於批量出題並導出),MuldivOrNot指定生成的四則運算表達式中是否容許有乘除法,BracketsOrNot指定生成的四則運算表達式中是否有括號,NegOrNot用於指定運算過程當中是否容許出現負數,FractOrNot用於指定運算過程當中是否出現分數。
  4. 給定一個合法的四則運算表達式判斷計算過程當中是否存在負數的狀況,若是存在返回1,不然返回0;
  5. 給定一個合法的四則運算表達式判斷計算過程當中是否存在除零錯誤,若是存在返回1,不然返回0;
  6. 給定導出題目位置以及相應答案位置,批量出題而且輸出至文件。

 

loose coupling設計思想主要體如今界面模塊,測試模塊和核心模塊的鬆耦合。

 

結對編程方法

  • Design by Contract
  • Code Contract

含義:

 

  1. Design by Contract,契約式編程,是一種計算機軟件的設計方法,這種方法要求軟件設計者爲軟件組件定義正式的,精確的而且可驗證的接口,爲傳統的抽象數據類型增長了前置條件後置條件不變式,「契約」在此是一種比喻,由於它和商業契約的狀況有點相似。
  2. 由於Design by Contract是屬於Eiffel Software的註冊商標,不少開發人員用契約式編程(Programming by Contract),契約編程(Contract Programming),或者契約優先式開發(Contract-First development)來指代這種方法。微軟也採用這種設計方法,稱爲代碼合約(Code Contracts)。

  摘自維基百科。

 

優勢:

  契約式編程在必定程度上減輕了編碼負擔和測試負擔,由於當使用契約編程時,程序員不須要對契約條件是否知足進行校驗,而是由代碼的調用者來保證前置條件的自動知足,而且只有在前置條件獲得知足的狀況下程序的執行纔是有意義的,而不知足前置條件代碼的執行狀況未知,這種未知不須要由程序員來定義。

 

不足:

  當程序的調用者在調用的過程當中因爲偶然的失誤致使程序的前置條件沒能知足,這時程序頗有可能出現未定義的情況,好比死循環,或者崩潰的錯誤。

 

應用:

  在這個項目中,須要實現契約編程的模塊是:表達式的計算模塊。

  • 前置條件要求傳入的參數是合法的四則運算表達式字符串,四則運算符和等號先後須要空格隔開。
  • 後置條件要求:  輸出一個字符串,字符串的值爲四則運算表達式的計算結果。
  • 不變式約束  在調用先後原表達式的字符串內容不發生任何變化。

爲了保證前置條件獲得知足,在表達式計算模塊調用以前使用正則表達式對於輸入的合法性進行驗證。

 

Unit test

 

第一次測試發現代碼的覆蓋率爲78.35%,分析結果顯示generateExpression()的代碼覆蓋率較差,因爲TestGenerateExp()測試中只測試了生成一個表達式,可能形成代碼分支覆蓋不徹底,故而設置循環,隨機生成100000個表達式,測試代碼以下:

1 [TestMethod]
2 void TestGenerateExp()
3 {
4     for (int i = 0; i < 100000; i++)
5     {    
6         generateExpression();
7     }        
8 };

改進的代碼覆蓋率以下圖:

 

第二次測試發現代碼的覆蓋率爲79.93%,個人心是崩潰的。。怎麼會這樣。。代碼覆蓋率竟然幾乎沒有提升?!難道是我打開VS的姿式不對?!仔細想想我使用setting()來設置隨機生成表達式的參數,在未設置的狀況下爲默認的,而在默認狀況下四則運算表達式的長度是3,長度有限,因此遍歷的可能性有侷限,setting()函數的參數以及含義寫在前面API中,第一個參數爲operatorNum,默認爲3,在這裏設置爲25。

 1 [TestMethod]
 2 void TestGenerateExp()
 3 {
 4     
 5     for (int i = 0; i < 100000; i++)
 6     {
 7         setting(25, 120, 150, 1, 1, 0, 1);
 8         generateExpression();
 9     }
10             
11 };

改進的代碼覆蓋率以下:

 

個人心獲得了些許的慰藉,果真代碼覆蓋率提升了很多。然而還不是特別理想,進一步考慮,generateExpression()中有許多參數的分支判斷,而使用setting(25, 120, 150, 1, 1, 0, 1)來設置參數限制了分支的執行種類,故而測試代碼改進爲以下:

 1 [TestMethod]
 2 void TestGenerateExp()
 3 {
 4     srand((unsigned)time(NULL));
 5     for (int i = 0; i < 100000; i++)
 6     {
 7         setting(rand() % 20 + 1, rand() % 20 + 1, rand() % 20 + 1, rand() % 2, rand() % 2, rand() % 2, rand() % 2);
 8         generateExpression();
 9     }
10             
11 };

 改進的代碼覆蓋率以下:

 

代碼覆蓋率提升到了91.15%,較爲滿意,然而generateExpression()仍是存在有未覆蓋到的代碼,還能夠繼續優化.......

 

UML圖

 因爲用C實現的基本功能,不存在類的概念,對於dll僅生成的相應的代碼函數關係圖以下:

 

界面的UML序列圖以下:

 

界面的代碼函數關係圖以下:

 

算法核心

   針對計算功能,首先根據正則表達式來過濾不合法的輸入狀況,而後經過接口調用C實現的計算模塊。計算模塊的實現主要是將兩個數統一轉換爲分子/分母的形式,再進行運算。

相關文章
相關標籤/搜索