20175205 結對編程項目-四則運算 總結博客

20175205 20175306 結對編程項目-四則運算 總結博客

需求分析(描述本身對需求的理解,以及後續擴展的可能性)

  • 需求分析
    • 用戶需求(每每不是真實需求)
    • 產品需求(對用戶需求提煉分析)
  • 需求分析的步驟
    • 挖掘真實需求(須要透過現象看本質,挖掘真實需求)
      • 目標用戶
      • 使用場景
      • 想要解決的問題
    • 提出解決方案(不僅侷限於用戶的需求)
    • 篩選和驗證方案

針對於本問題:java

用戶需求

  • 自動生成小學四則運算題目(加、減、乘、除);支持整數;支持多運算符(好比生成包含100個運算符的題目);支持真分數;統計正確率
  • 擴展需求:文件,處理生成題目並輸出到文件,完成題目後從文件讀入並判題;多語言支持:簡體中文, 繁體中文, English;生成題目去重git

    分析需求

  • 挖掘真實需求:
    • 目標用戶:小學生
    • 使用場景:小學生進行數學有關四則運算題目的測試
    • 想要解決的問題:設計一個可讓學生測試的程序
  • 提出問題和解決方案:讓用戶能夠進行數學測試,能夠是數學四則運算測試,還能夠是"開根號,冪運算"等等,還能夠支持更多語言。編程

設計思路(同時輸出UML類圖)

上課講了SOLID原則,反看第一週完成的代碼,那都是個什麼玩意,充分的知足了「低內聚,高耦合」,添加新要求的時候,一動都得動,無從下手,所以我決定從新修改,試着向SOLID原則靠攏,這樣下次再添加什麼需求的時候就不用全篇「大動」。windows

SOLID

  • 單一職責原則(高內聚):讓一個類只作一種類型責任,當這個類須要承當其餘類型的責任的時候,就須要分解這個類。
  • 開放封閉原則:對擴展是開放的,而對修改是封閉的。
  • 代替原則:當一個子類的實例應該可以替換任何其超類的實例時,它們之間才具備is-A關係
  • 接口分離原則:不能強迫用戶去依賴那些他們不使用的接口。換句話說,使用多個專門的接口比使用單一的總接口總要好。
  • 依賴倒置原則(低耦合)高層模塊就不該該依賴於底層模塊,兩者都應該依賴於抽象模塊

本週設計

  • 用戶後期需求也許還會增長除了+、-、*、÷、()、/ 之外的符號好比須要開根號,求冪運算等等,所以我還增長了產生數學題目的抽象類
  • 增長真分數的狀況,並且要添加真分數的運算,注意分母爲零的狀況
  • 針對於不一樣年齡段的學生,可能掌握的能力也不一樣,所以我對此也作了更改。好比,一年級能作加減運算;二年級能作乘除運算;三年級能作含括號的運算;其餘年級就可作分數運算。
  • 處理生成所有題目並輸出到文件,並從文件讀入並判題
  • 多語言支持:簡體中文, 繁體中文, English
  • 生成題目去重:通過分析,我認爲就是運算符多於一個的題目,只要後綴表達式相同,那麼就是重複的式子,所以我從這個角度進行了修改。可是後來和其餘組同窗討論,發現這種方法並不全面,有很大的漏洞。。。

實現過程當中的關鍵代碼解釋

import java.util.Locale;
import java.util.ResourceBundle;
public abstract class Language {
    public abstract void Print(String s);
}
public class Chinese extends Language{
    public Chinese(){}
    public void Print(String s){
        Locale locale1 = new Locale("zh","CN");
        ResourceBundle res1 = ResourceBundle.getBundle("zh_CN",locale1);
        System.out.print(res1.getString(s));
    }
}
public class English extends Language{
    public English(){}
    public void Print(String s) {
        Locale locale2 = new Locale("en", "US");
        ResourceBundle res2 = ResourceBundle.getBundle("en_US", locale2);
        System.out.print(res2.getString(s));
    }
}
public class TChinese extends Language {
    public TChinese(){}
    public void Print(String s){
        Locale locale3 = new Locale("zh","TW");
        ResourceBundle res3 = ResourceBundle.getBundle("zh_TW",locale3);
        System.out.print(res3.getString(s));
    }
}

注:此處代碼是爲了實現程序的多語言切換(國際化),軟件實現國際化,需具有如下兩個特徵:
一、對於程序中固定使用的文本元素,例如菜單欄、導航條等中使用的文本元素、或錯誤提示信息,狀態信息等,須要根據來訪者的地區和國家,選擇不一樣語言的文本爲之服務。
二、對於程序動態產生的數據,例如(日期,貨幣等),軟件應能根據當前所在的國家或地區的文化習慣進行顯示。設計模式

if(s1.equals("1")&&(s2.equals("1")==false)){
            Numerator1 = 1;
            Denominator1 = 1;
            str2 = s2.split("/");
            Numerator2 = Integer.parseInt(str2[0]);
            Denominator2 = Integer.parseInt(str2[1]);
        }
        else if(s2.equals("1")&&(s1.equals("1")==false)){
            Numerator2 = 1;
            Denominator2 = 1;
            str1 = s1.split("/");
            Numerator1 = Integer.parseInt(str1[0]);
            Denominator1 = Integer.parseInt(str1[1]);
        }
        else if(s1.equals("1")&&s2.equals("1")){
            Numerator1 = 1;
            Denominator1 = 1;
            Numerator2 = 1;
            Denominator2 = 1;
        }
        else{
            if((s1.contains("/")==true)&&(s2.contains("/")==false)){
                str1 = s1.split("/");
                Numerator2 = Integer.parseInt(s2);
                Denominator2 = 1;
                Numerator1 = Integer.parseInt(str1[0]);
                Denominator1 = Integer.parseInt(str1[1]);
            }
            else if((s2.contains("/")==true)&&(s2.contains("/")==false)){
                Numerator1 = Integer.parseInt(s1);
                Denominator1 = 1;
                str2 = s2.split("/");
                Numerator2 = Integer.parseInt(str2[0]);
                Denominator2 = Integer.parseInt(str2[1]);
            }
            else if((s2.contains("/")==false)&&(s2.contains("/")==false)){
                Numerator1 = Integer.parseInt(s1);
                Denominator1 = 1;
                Numerator2 = Integer.parseInt(s2);
                Denominator2 = 1;
            }
            else{
                str1 = s1.split("/");
                str2 = s2.split("/");
                Numerator1 = Integer.parseInt(str1[0]);
                Denominator1 = Integer.parseInt(str1[1]);
                Numerator2 = Integer.parseInt(str2[0]);
                Denominator2 = Integer.parseInt(str2[1]);
            }
        }

這個部分是我一開始沒有想到的狀況,經過測試等手段發現了分母爲零的狀況,不是分數的狀況。數組

測試方法

運行過程截圖



代碼託管

遇到的困難及解決方法

Q: 將帶有÷號的題目輸入文件,卻出現了亂碼。。。心態爆炸,原本好好的程序,加了個文件就輸不出來了???
A:原來是系統的編碼和程序的編碼採用了不一樣的編碼格式。在用Java程序進行讀寫含中文的txt文件時,常常會出現讀出或寫入的內容會出現亂碼。一般,假如本身不修改的話,windows自身採用的編碼格式是gbk(而gbk和gb2312基本上是同樣的編碼方式),而IDE中Encode不修改的話,默認是utf-8的編碼,這就是爲何會出現亂碼的緣由。當在OS下手工建立並寫入的txt文件(gbk),用程序直接去讀(utf-8),就會亂碼。爲了不可能的中文亂碼問題,最好在文件寫入和讀出的時候顯式指定編碼格式。所以,我在輸入讀寫文件上作了改動,代表了編碼格式!!學習

try{
                    OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(file),"gbk");
                    BufferedWriter writer = new BufferedWriter(write);
                    writer.write(t);
                    writer.write(" = ");
                    writer.close();
                }
                catch (IOException e){}
                try{
                    InputStreamReader read = new InputStreamReader(new FileInputStream(file),"gbk");
                    BufferedReader reader = new BufferedReader(read);
                    System.out.print(reader.readLine());
                    read.close();
                }
                catch (IOException e){}

Q:多語言支持是什麼鬼。。。就一直if-else??
A:Java中有ResourceBundle這樣的類,能夠作到測試

  • 輕鬆地本地化或翻譯成不一樣的語言
  • 一次處理多個語言環境
  • 之後能夠輕鬆進行修改,以便支持更多的語言環境
    這個類的做用就是讀取資源屬性文件(properties),而後根據.properties文件的名稱信息(本地化信息),匹配當前系統的國別語言信息(也能夠程序指定),而後獲取相應的properties文件的內容。具體實施就是:
  • 在src目錄下建後綴爲properties的文件,個人理解是,能夠一個語言體系建一個對應的讀取資源屬性文件
  • 文件裏面放的內容是我想輸出的字符串所對應的ASCII(可用ASCII轉換器)
  • 我建了一個Language的類,裏面包含3個方法,分別是中英繁體的實現;須要英文時,就調用實現英文的方法便可

Q:如何實現去重
A:我一開始的想法是,只要後綴表達式相同,那麼就是相同的題目,但通過和夥伴討論以後,又產生了新的想法,將每次進行運算的num1 op num2放入一個數組中,只要兩個數組徹底相同,那麼就是相同的題目。(想法還在實施中)優化

對結對的小夥伴作出評價(重點指出須要改進的地方)

哇,小夥伴簡直過重要了,我聽了老師的各類原則以後,看個人程序簡直是一團亂麻,剪不斷理還亂,藕斷絲連,你中有我,我中有你。。。所以我決定,按照SOLID原則及需求分析步驟,和個人小夥伴激烈討論,給我提供了很是好的思路,從新整理了個人程序。我發現,在完成擴展內容的時候,就能夠作到對外擴展,對內封閉,很是開心!和小夥伴的合做很順利,咱們分工明確,積極討論,互相改錯,相互進步,在這次結對學習過程當中受益不淺,不只對知識點有了鞏固和拓展,還對編程的思路方式等有了新的模式。編碼

參考

Java讀寫txt文件時防止中文亂碼問題出現的方法介紹
JAVA中ResourceBundle使用詳解

PSP

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃
• Estimate • 估計這個任務須要多少時間 600 900
Development 開發
• Analysis • 需求分析(包括學習新技術) 20 30
• Design Spec • 生成設計文檔 20 30
• Design Review • 設計複審 20 30
• Coding Standard • 代碼規範 (爲目前的開發制定合適的規範) 20 40
• Design • 具體設計 30 40
• Coding • 具體編碼 400 600
• Code Review • 代碼複審 30 40
• Test • 測試(自我測試,修改代碼,提交修改) 20 30
Reporting 報告
• Test Repor • 測試報告 10 20
• Size Measurement • 計算工做量 10 10
• Postmortem & Process Improvement Plan • 過後總結, 並提出過程改進計劃 20 30
合計 600 900

總結學到的內容

此次作結對項目本着能夠學到東西的目的,我對本身的代碼的大體模型改了不少次,第一週本身嘗試的時候雖然作出了符合要求的程序,可是內在關係仍是很是雜亂的,徹底不知足SOLID原則;在聽了相關講解以後,對設計模式,如何作需求分析,怎樣寫出高內聚低耦合的程序有了必定的瞭解,所以我努力的對本身的程序不斷修改,努力完成一份符合設計原則的代碼;在個過程當中遇到了很是多的問題,解決完這個問題,又會產生下個問題等待優化,我不得不上網百度,和同窗討論,這樣兩個思想的碰撞產生的是無窮的力量,不只增長了個人知識儲備,還大大提升了本身的抗壓能力,寫完代碼很是有成就感。

相關文章
相關標籤/搜索