我的第四次做業:結對編程

我的第四次做業:結對編程

閱讀與準備做業

本做業屬於的課程html

https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesigngit

本做業的要求github

http://www.javashuo.com/article/p-zywsxnlu-cu.html編程

隊友博客c#

https://www.cnblogs.com/zwj-958654064/數組

隊友學號服務器

201731062520函數

 

一、Github項目地址:

https://github.com/jie958654064/WordCount性能

二、PSP表格

PSP2.1單元測試

Personal Software Process Stages

預估耗時(分鐘)

Planning

計劃

 35

 Estimate

 估計這個任務須要多少時間

 65

Development

開發

 50

 Analysis

 需求分析 (包括學習新技術)

 15

 Design Spec

 生成設計文檔

 10

 Design Review

 設計複審 (和同事審覈設計文檔)

 10

 Coding Standard

 代碼規範 (爲目前的開發制定合適的規範)

 5

 Design

 具體設計

 20

 Coding

 具體編碼

 90

 Code Review

 代碼複審

 45

 Test

 測試(自我測試,修改代碼,提交修改)

 60

Reporting

報告

 100

 Test Report

 測試報告

 45

 Size Measurement

 計算工做量

 20

 Postmortem & Process Improvement Plan

 過後總結, 並提出過程改進計劃

 15

 

合計

 585

 

3、計算模塊接口的設計與實現過程

3.1接口與設計類圖展現以下

 

3.2分工實現過程

這裏我和個人隊友將單詞統計這個程序分爲了兩個部分進行分別開發最後再經過將我隊友的代碼封裝成類庫用他的方法,這裏咱們的分工是個人隊友主要設計StatisticalWordCount項目,主要是計算文章的總字符個數、總文本的單詞書、以及行數字母的頻數、以及將單詞頻數進行排序等功能,最後他將他的功能進行封裝成dll類庫供我調用他的方法。

我設計的是CalculateWordCount項目,主要是設計文件的cmd讀入命令、添加引用調用他封裝的dll對單詞的全部統計方法,讀取單詞文件、以及最後將結果輸出到文本中、以及最後設計的一個可展現的界面,將cmd命令轉入到form上進行用戶自輸入,以實現到導入單詞文本文件或者用戶自動輸入文本提交,點擊導出按鈕輸出統計結果。

3.3部分代碼

統計接口:Statistical

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WordCount
{
  
    public interface Count
    {
        //計算總字符個數
        int count_Char(string inpath);

        //計算文本中總單詞數
        int count_Word(string inpath);

        //計算文本總行數
        int count_Line(string inpath);

        //計算文本中每一個單詞出現的次數
        Dictionary<string, int> count_Dictionary(string inpath);

        //將字母按頻數降序排序
        Dictionary<string, int> sort_Dictionaryby_desc(Dictionary<string, int> my_dic);

        //將結果寫入文件
        void Write_to_txt(string inpath, string outpath);
    };

    public class Statistical
    {
        static void Main(string[] args)
        {
            
        }

    }
}

實現統計接口:count

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace WordCount
{
   public class count:Count
    {
        //將結果寫入文件,inpath爲讀入文件路徑(如下inpath均爲讀入文件路徑),outpath爲寫入結果文件路徑
        public void Write_to_txt(string inpath, string outpath)
        {
            count mycount = new count();
            int count_word = mycount.count_Word(inpath);          //調用計算總單詞數方法,結果保存在count_word
            int count_char = mycount.count_Char(inpath);          //調用計算總字符數方法,結果保存在count_char
            int count_line = mycount.count_Line(inpath);          //調用計算總行數方法,結果保存在count_line
            StreamWriter sw = null;
            
            //調用計算單詞出現次數並排序的方法,將結果保存到dictionary字典中
            Dictionary<string, int> a = mycount.sort_Dictionaryby_desc(mycount.count_Dictionary(inpath));
            if (outpath == null)
            {
                sw = new StreamWriter(@"C:\Users\傑\Desktop\out.txt");          //在默認位置建立寫文件流
            }
            if (outpath != null)
            {
                sw = new StreamWriter(outpath);                                  //在outpath路徑建立寫文件流
            }

            //把結果寫入文件
            Console.SetOut(sw);
            Console.WriteLine("字符數:" + count_char);
            Console.WriteLine("單詞數:" + count_word);
            Console.WriteLine("行數:" + count_line);
            Console.WriteLine("單詞出現次數以下:");

            //遍歷a字典裏面的每一條信息
            foreach (KeyValuePair<string, int> pair in a)
            {
                int value = pair.Value;
                string key = pair.Key;
                Console.WriteLine("{0}:  {1}", key, value);
            }
            sw.Flush();
            sw.Close();
        }

        //計算並返回總字符個數
        public int count_Char(string inpath) 
        {
            //在inpath路徑建立讀文件流
            StreamReader sr = new StreamReader(inpath);
            string s;
            char[] char_array;
            int allchar = 0;

            //讀取文件的每一行
            while ((s = sr.ReadLine()) != null)
            {
                //將讀取的每一行送入char數組中
                char_array = s.ToCharArray();
                for (int j = 0; j < char_array.Length; j++)
                {
                    //計算每個字符
                    allchar++;
                }
            }
            return allchar;
        }

        //計算每一個單詞出現的次數,結果傳入字典並返回,字典中的key是單詞的值,value是單詞出現的次數
        public Dictionary<string, int> count_Dictionary(string inpath)
        {
            //在inpath路徑建立讀文件流
            StreamReader sr = new StreamReader(inpath);
            string s;
            Dictionary<string, int> dictionary = new Dictionary<string, int>();

            //讀取文件的每一行到字符串s
            while ((s = sr.ReadLine()) != null)
            {
                //將字符串s按空格分割,即劃分每個單詞
                string[] words = Regex.Split(s, " ");
                //計算每行各個單詞數
                foreach (string word in words)

                // 判斷字典是否包含該單詞,若包含,該單詞出現次數加一,若不包含,將該單詞添加到字典
                    if (dictionary.ContainsKey(word))
                    {
                        dictionary[word]++;
                    }
                    else
                    {
                        dictionary[word] = 1;
                    }
                }
            return dictionary;
        }

        //計算並返回總行數
        public int count_Line(string inpath)
        {
            //在inpath路徑建立讀文件流
            StreamReader sr = new StreamReader(inpath);
            string s;
            int line = 0;
            //讀取文件總行數
            while ((s = sr.ReadLine()) != null)
            {
                line++;
            }
            return line;
        }

        //計算總單詞個數
        public int count_Word(string inpath)
        {
            count doCount = new count();
            Dictionary<string, int> dictionary = doCount.count_Dictionary(inpath);
            int allword = 0;

            //遍歷字典裏面的每個單詞,結果爲總單詞數
            foreach (KeyValuePair<string, int> dic in dictionary)
            {
                allword += dic.Value;
            }
            return allword;
        }

        //將字母按出現次數降序排序
        public Dictionary<string, int> sort_Dictionaryby_desc(Dictionary<string, int> my_dic)
        {
            List<KeyValuePair<string, int>> my_List = new List<KeyValuePair<string, int>>(my_dic);
            //按value比較兩個單詞,並按value大小排序
            my_List.Sort(delegate (KeyValuePair<string, int> s1, KeyValuePair<string, int> s2)
            {
                return s2.Value.CompareTo(s1.Value);
            });
            my_dic.Clear();
            //遍歷整個字典,並按value值爲字典排序
            foreach (KeyValuePair<string, int> pair in my_List)
            {
                if (pair.Key != null && pair.Key != ":" && pair.Key != "," && pair.Key != ".")
                    my_dic.Add(pair.Key, pair.Value);
            }
            return my_dic;
        }
    }
}

 

3.4運行過程:

這裏我在網上找了一篇文章,存入了K:\text.txt文件中,以後經過cmd使用命令CalculateWordCount.exe -i k:\text.txt -m 3 -n 10 -o k:\output.txt去讀它:

 

四、代碼複審

4.一、設立的代碼規範

我跟我隊友以前合做過不少次,包括一些比賽或者是外面接的一些活,因此配合的仍是頗有默契,也有必定的代碼能力,因此題目下來了咱們就仔細讀了一下要求肯定了咱們一塊兒遵照的代碼規範以下:

1.一個文件中只放一個類,類名同文件名,不要在一個文件中寫好幾個類,這樣看的清楚。

2.不要在一個文件中寫多於500行的代碼,除了那些比較大的實體類。其實我還想說超過500行看起來就有點累,可是在咱們的系統中超過1000行的代碼比比皆是。

3.一個方法的代碼不要超過100行,其實我想說超過50行的方法看起來就有點累。可是在咱們的系統中超過200行代碼的方法比比皆是。

4.存儲過程的代碼也不要超過100行,不要在存儲過程當中寫過多的業務邏輯,可是在咱們的模塊中我還真的見過1000多行的存儲過程,好宏偉啊!

5.避免寫超過5個參數的方法,若是有請使用一個類或者結構來傳。

6.一個方法只有一個return result; ,不要屢次return結果,最好給返回結果賦值,最後return result;

7.不要給很簡單的代碼加註釋,會有噪音的,會讓人誤解的,由於你寫的大多數狀況下很片面。

8.記錄日誌的時候不要處處都記,有條件的狀況下針對客戶一次操做(好比下單)只記錄一條日誌。

4.2相互檢查過程

在他寫好統計單詞的方法封裝完dll,以及我按照提早約定寫好相應的接口和調用他那邊的方法以後,咱們就開始相互檢查對方的代碼,相互提出意見,基本知足咱們提早的約定規範,遇到的問題他那邊忘記把類公用,致使封裝以後我這邊一直添加引用找不到方法,最後改了以後二者就成功融合了。

五、計算模塊接口部分的性能改進

5.1改進一:

以前設計的時候我隊友將StatisticalWordCount,包括統計字符個數、總行數、字母頻數出現整個冗餘在main主函數裏面,建議他改了以後設計一個抽象Statistical類,最後將具體詞頻統計的各個功能進行分離,使用工廠方法模式,將代碼重構,方便了以後若是要增長其餘功能,可直接添加其餘具體操做詞頻的具體工廠便可,就無須整個改動代碼。

StatisticalWordCount改進以後的類圖:

 

5.2改進後性能測試:

總體性能分析:

 

具體產品角色檢測性能:

 

六、 計算模塊部分單元測試展現

這裏我分別設計了四個測試分別檢測我隊友寫的dll類庫以及我本身寫的計算的模塊和檢驗擴展功能的字符自動輸入和導入功能是否正常使用。

測試計算文章總行數:

 

測試計算每一個單詞出現的次數:

 

測試計算文章總的字母個數:

 

測試將輸入寫入文件:

 

最終效果:

 

七、 計算模塊部分異常處理說明

針對在計算模塊的異常處理主要是集中在我隊友對詞頻統計那個模塊和我讀入文件中,這裏主要遇到了並解決了三種異常處理。首先是對詞頻統計的數組集合作處理越界元素類型以及其餘非檢查異常。第二種異常就是,處理的是在加載庫的時候類的訪問運行異常處理;第三種就是針對文件的讀出或者寫入的IO作運行異常處理。

解決的話我就是用的常見的c#中提供try 和catch塊提供得一種結構化的異常處理方案, try catch自己並不會影響系統的性能,在沒有發生異常的時候try catch 是不會影響系統性能的。受影響的時候是發生異常的時候。 

關鍵字 try catch finally。先執行try裏面的語句,若是拋出異常就會被catch捕獲。不管出不出現異常都會執行finally裏面的語句。另外不經常使用的throw關鍵字:當問題出現時,程序拋出一個異常。

 

 八、描述結對的過程

結對顧名思義咱們就是首先查資料進行分工,這裏我和個人隊友將單詞統計這個程序分爲了兩個部分進行分別開發最後再經過將我隊友的代碼封裝成類庫用他的方法,這裏咱們的分工是個人隊友主要設計StatisticalWordCount項目,主要是計算文章的總字符個數、總文本的單詞書、以及行數字母的頻數、以及將單詞頻數進行排序等功能,最後他將他的功能進行封裝成dll類庫供我調用他的方法。

我設計的是CalculateWordCount項目,主要是設計文件的cmd讀入命令、添加引用調用他封裝的dll對單詞的全部統計方法,讀取單詞文件、以及最後將結果輸出到文本中、以及最後設計的一個可展現的界面,將cmd命令轉入到form上進行用戶自輸入,以實現到導入單詞文本文件或者用戶自動輸入文本提交,點擊導出按鈕輸出統計結果。

爲了爭分奪秒每次咱們都會在每次有課以前提早到爭取時間進行商議結伴編程:

 

 

9PSP表格記錄下你在程序的各個模塊上實際花費的時間

PSP2.1

Personal Software Process Stages

預估耗時(分鐘)

實際耗時(分鐘)

Planning

計劃

 35

45 

 Estimate

 估計這個任務須要多少時間

 65

 60

Development

開發

 50

 60

 Analysis

 需求分析 (包括學習新技術)

 15

 15

 Design Spec

 生成設計文檔

 10

 15

 Design Review

 設計複審 (和同事審覈設計文檔)

 10

 10

 Coding Standard

 代碼規範 (爲目前的開發制定合適的規範)

 5

 5

 Design

 具體設計

 20

 30

 Coding

 具體編碼

 90

 120

 Code Review

 代碼複審

 45

 60

 Test

 測試(自我測試,修改代碼,提交修改)

 60

80

Reporting

報告

 100

100

 Test Report

 測試報告

 45

50

 Size Measurement

 計算工做量

 20

 20

 Postmortem & Process Improvement Plan

 過後總結, 並提出過程改進計劃

 15

 10

 

合計

 585

 950

 

十、附加功能

結合老師的博客要求增長的功能,這裏進行設計我這裏對老師發佈的要求的理解「提供可供用戶交互的按鈕和,實現-i -m -n -o 這四個參數的功能」應該就是設計一個能夠供用戶與系統交互的界面,也就是實現咱們以前設計的cmd讀入-i -m -n -o命令的效果。設計效果以及最終測試以下:

首界面:

 

10.1首先演示第一種自動導入:

直接導入文件:

 

 

10.1首先演示第二種文本框輸入:

我先把測試文件複製粘貼過來到文本框裏,就不導入文件了,直接輸入mn點擊開始統計,最終存入文件和顯示在屏幕上:

 

10.3檢驗是否成功

 

最終於前面設計的基礎cmd運行效果同樣,證實設計擴展成功。

十一、代碼提交

這裏咱們git總共分了三次提交,第一次就是在寫好我和隊友個本身功能模塊後進行提交。第二個版本就是,我將隊友的功能添加好類庫引用拼接好以後實現cmd 的單詞詞頻統計後的提交。第三次就是在整合好前面的功能後,將第二個版本生成類庫供窗體應用程序添加引用,最後實現用戶的交互。

第一個版本:

 

 

 

第二個版本:

第三個版本:

 

 

 

總結

由於和隊友以前就又過不少次合做,因此此次合做的仍是比較順利,對於本次的結對編程又一次體會到了兩我的按照必定的約束規則進行合做而產生1+1>2的的效果,也真正感覺到告終對編程的好處與魅力,在此次過程當中經過代碼互審找出我和隊友的不足並及時改正,並經過這樣的過程使本身不對總結經驗和本身的不足並不斷提高。

經過此次也對技術也有了一點的深入認識,特別是此次對異常處理,加上以前在作C#項目的一些比賽或者私活中時,我也思考過如何有效地在項目團隊中實踐異常的處理。 我以爲首先,異常處理應該是系統設計規約的一部分出如今系統設計文檔中,而不只僅是一種技術實現。

做爲設計文檔的一部分,異常處理應該着眼於系統容錯性和穩定性。而後在根據這個規約,再來具體討論和選擇異常處理中使用的各類技術細則。 好比,在設計功能服務時,必須在功能服務的調用接口處有異常處理,不然客戶端傳過來的任何有害數據均可能讓服務器掛掉。 並且對異常的處理在系統的設計中,必須有明確說明,不能隨便在哪一個模塊中處理異常。 以上是本身對異常處理的我的見解。

相關文章
相關標籤/搜索