Java项目开发全流程实践
文章導讀
【項目遵循需求分析、程序設計、編碼、測試、運行標準開發過程, 從分析項目問題入手,提出解決方案,應用對象建模工具UML設計系統,依據設計文檔進行編碼。】
問題描述:實現一個簡單的四則運算器。滿足用戶在Windows命令行窗口可以進行簡單四則運算的要求。
?
1、四則運算具體功能要求:
(1)實現帶單個運算符表達式的計算;
(2)用戶可以重復輸入表達式進行計算;
(3)輸入quit退出程序;
(4)顯示程序幫助內容。
?
2、角色劃分與用例描述
角色是與程序相關的人和物,是指程序以外的,在使用程序或與程序交互中所扮演的角色。例如:使用程序的人、程序運行所依賴的環境等,本節主要討論程序與人相關的角色。
本程序涉及的角色只有一個,就是程序的使用者,使用者輸入算式,程序給出算式結果;使用者輸入quit命令,程序退出;當使用者不熟悉該程序如何使用時,使用者可以查看程序給出的幫助說明。
?
本程序采用用例圖對角色功能進行描述,通過用例圖對功能需求進行分析和整理,繪制用例圖的過程就是程序建模過程,建立的模型就是用例模型。
通過角色分析可知,程序使用者有三個用例模型,分別是輸入算式、退出程序、查看幫助。
?
3、用例圖
在一個用例圖中通常有三種元素:參與者(Actor)、用例(Use Case)與程序邊界(Boundary)。用例描述的是程序為用戶提供的功能,也就是程序能為用戶做什么,圖例符號為一個橢圓;參與者是表1中劃分的角色,也就是程序的使用者,圖例符號為一個小人兒;最后是程序邊界,程序邊界描述了程序本身實現的功能與外部交互的邊界,例如:參與者在程序邊界之外,用例在程序邊界之內,圖例符號為一個方框。
(1)算式計算用例圖(U001)
算式計算用例包含5個子用例,其中<輸入算式>用例、<算式求解>用例、<查看答案>用例和使用者有交互行為,<計算算式>用例和<掃描算式>用例為內部用例,由<算式求解>用例調用并使用,<掃描算式>用例掃描算式,如果發現算式錯誤,由算式求解返回錯誤給使用者。
(2)退出程序用例圖(U002)
該用例包含兩個子用例,用例<輸入判斷>用于判斷用戶輸入的字符串,如果字符串等于“quit”,調用<退出程序>用例退出程序。
(3)查看幫助用例圖(U003)
?
該用例包含兩個子用例,用例<輸入判斷>用于判斷用戶輸入的字符串,如果字符串等于“help”,調用<輸出幫助內容>用例顯示幫助內容。
?
4、根據需求設計程序
前面需求分析階段給出了角色、用例和業務流程。設計階段需要將需求階段給出的角色、用例和業務流程模型映射到能夠被編程語言識別和描述的對象、對象功能和對象行為模型,設計階段用到的UML模型有類圖、活動圖、時序圖、狀態圖、部署圖、偽代碼。
設計階段需要針對需求階段給出的角色與用例,規劃出對象類。在UML設計模型中,一般將對象類分為邊界類、控制類和實體類。邊界類主要用于描述外部參與者與程序之間的交互。例如:角色“程序使用者”同四則運算器的交互行為,其交互行為有“程序使用者”輸入算式、查看幫助、退出程序等;控制類用于描述程序的控制流程。例如:四則運算器開始運行后,需要持續等待用戶輸入命令或算式,根據用戶輸入的內容選擇不同的流程;實體類一般用于事物、人員或者一些現實生活中的對象,該類對象有存儲數據的要求。例如:如果四則運算器要求區分角色“程序使用者”并存儲角色信息時,就需要為角色“程序使用者”建立實體類,以便程序存儲每個“程序使用者”的信息。
四則運算器的角色“程序使用者”并沒有存儲其信息的要求,因此無需為該角色建立實體類。與該角色相關的有三個用例,分別是<輸入算式>用例、<算式求解>用例和<查看答案>用例,該三個用例都有流程控制和外部交互需求,故分別需要為這三個用例建立控制類和邊界類。從設計實用性、編程效率方面考慮,可以將控制類和邊界類合并為一個控制類;但從可維護性和擴展性上考慮,分開設計有利于代碼結構清晰、并易于擴展四則運算器的功能。具體選擇什么樣的設計模式,需要根據程序(系統)所處的環境、技術、資源來決定,例如:一個程序(系統)在交付日期已經確定,項目進度緊張,而技術和人力資源又出現問題的情況下,應以設計實用性、編程效率方面考慮,反之則應從可維護性和擴展性上考慮。本節主要用于說明如何根據需求分析歸納類對象,從簡單易懂考慮,采用合并設計原則。
類名命名為“Arithmetic”,類名確定后,需要根據用例及業務流程圖歸納類的屬性和方法。
從前面的用例圖和業務流程圖分析可知,程序主要涉及到算式、幫助內容、錯誤信息三部分信息,這三部分信息都有被程序修改內容和獲取內容的需要,因此可以歸納為“Arithmetic”類的屬性。類的屬性不同于類的成員變量,類的屬性可以通過get方法獲取屬性內容,通過set方法設置屬性內容。
一般來說,用例圖中的子用例都可以歸納為類的方法。例如:用例<算式計算>的子用例<<輸入算式>>、<<計算算式>>、<<掃描算式>>等都可以歸納為類的方法。
?
圖4 Arithmetic類圖
?
類圖說明
?
類圖設計完成后,根據設計的需要,可能還需要設計活動圖、時序圖、狀態圖、部署圖等。其多用于復雜的程序(系統)進一步理順業務活動、流程、事件、部署等設計需要。本程序結構簡單,無需再設計活動圖,類圖設計完成后,基本就可以進入編碼了。
?
程序流程控制功能
程序啟動運行后,首先顯示幫助內容,向用戶提示程序的使用方法。然后循環等待用戶輸入,用戶輸入完成后,程序根據用戶輸入的選擇不同的分支執行程序。若輸入的內容為“quit”,則執行退出程序分支;若輸入的內容為“help”,則執行顯示幫助程序分支;若不是前兩項內容,則執行算式計程序分支。分支執行完畢,繼續等待用戶輸入。程序控制流程如下圖所示:
圖5 程序控制流程圖
算式計算功能
計算算式并返回計算結果,計算前先對算式做語法判斷,若算式語法錯誤,返回錯誤信息,終止計算功能。若算式語法正確,計算算式并返回計算結果。算式計算流程如下圖所示:
圖6 算式計算流程圖
5、根據設計編寫代碼
程序流程控制
節程序流程控制功能一段給出了流程描述。按照流程描述,需要實現如下功能。
(1)建立run方法,在main方法中調用
?
在main方法中,聲明類型為Arithmetic類成員變量tempArithmetic,并調用new方法初始化,然后調用Arithmetic類的run方法。
(2)顯示幫助內容
需求部分要求幫助內容及顯示格式如下:
***歡迎使用四則運算器***
算式計算:輸入算式后,按下回車鍵,程序給出答案。算式僅限于算式僅支持包含單個運算符和兩個運算數的算式。例如:15+20、8*9、20/5等。
退出程序:請輸入“quit”命令,按下回車鍵。
查看幫助:請輸入“help”命令,按下回車鍵。
Arithmetic類屬性“help”存儲幫助內容,showHelp()方法顯示幫助內容。在Arithmetic類方法run中添加如下代碼:
(3)循環等待用戶輸入
在程序頂部導入java.util包,在run方法中添加while循環代碼,在循環體添加獲取用戶輸入代碼。
在run方法中,添加do-while循環語句,循環接收用戶的輸入,該循環為無限循環,后續代碼需要添加退出循環語句。
(4)判斷用戶輸入內容,選擇不同程序分支
根據用戶輸入的內容,程序流程有三個分支。若輸入的內容為“quit”,調用Arithmetic類的quit方法退出程序;若輸入的內容為“help”,調用Arithmetic類的showHelp方法;若不是前兩項內容,
調用Arithmetic類的calculateFormula方法。在run方法do-while循環語句中增加if-else語句。
?
算式計算
計算算式并返回計算結果,計算前先對算式做語法判斷,若算式語法錯誤,返回錯誤信息,終止計算功能。若算式語法正確,計算算式并返回計算結果。
(1)語法掃描
掃描用戶輸入的算式,檢查算式語法是否符合程序要求。語法正確與否判斷規則如下:
● 算式的開始和結束字符必須是數字;
● 算式只能包含數字和‘+’、‘-’、‘*’、‘/’運算符;
● 運算符不能連續;
● 運算符有且只能包含一個;
在Arithmetic類的scanFormula方法添加如下代碼:
/*** Function scanFormula * Description: 掃描formula算式,返回掃描結果 * input: 無輸入參數 * return: formula算式無語法錯誤,返回sucess,否則返回語法錯誤 */ public String scanFormula() { String result = "sucess"; String strFormula = getFormula(); char ch; //聲明count變量,存儲運算符的出現的次數 int count=0; //遍歷strFormula for( int i = 0; i < strFormula.length(); i++ ) { //獲取strFormula的第i個字符 ch = strFormula.charAt(i); /** * 判斷ch是否是合法字符 * 合法字符為數字和‘+’、‘-’、‘*’、‘/’運算符 */ if(ch >='0' && ch <='9') { continue; } elseif( ch=='+' || ch=='-' || ch=='*' || ch=='/' ) { count++; //算式的第一個字符和最后一個字符不能是運算符 if( i == 0 || i == strFormula.length()-1 ) { result = "算式的第一個字符和最后一個字符不能是運算符"; break; } //算式只能包含一個運算符 if( count >= 2 ) { result = "輸入的算式只能包含一個運算符"; break; } } else { result = "輸入的算式包含非法字符,算式的第(" + i + ")個字符為非法字符"; break; } } return result; }語法掃描采用遍歷算式所有字符的算法,對算式的每個字符進行判斷。for循環遍歷算式的所有字符,for循環體的if-else語句判斷算式的單個字符是否符合語法要求,如果不符合要求,設置語法錯誤信息并跳出循環。
(2)計算算式
具體算法為:遍歷并解析算式,得到運算數和運算符,然后利用switch語句控制不同的計算分支,得到計算結果。
在Arithmetic類的calculateFormula方法添加如下代碼:
/*** Function calculateFormula * Description: 計算formula存儲的算式,返回計算后的結果 * input: 無輸入參數 * return: 返回計算后的結果 */ public String calculateFormula() { String result = ""; //聲明num1和num2變量,用于存儲運算數 String num1 = ""; String num2 = ""; //聲明op,用于存儲運算符 String op = ""; char ch; //判斷 boolean bFirst = true; String strFormula = getFormula(); //遍歷strFormula for( int i = 0; i < strFormula.length(); i++ ) { //獲取strFormula的第i個字符 ch = strFormula.charAt(i); if(ch >='0' && ch <='9') { if( bFirst ) num1 += ch; else num2 += ch; } elseif( ch=='+' || ch=='-' || ch=='*' || ch=='/' ) { bFirst = false; op += ch; } } //計算算式 //獲取運算符 ch = op.charAt(0); //將字符串強制轉換為double類型 double dNum1 = Double.parseDouble(num1); double dNum2 = Double.parseDouble(num2); double dResult = 0.0; switch(ch) { case'+': dResult = dNum1 + dNum2; break; case'-': dResult = dNum1 - dNum2; break; case'*': dResult = dNum1 * dNum2; break; case'/': { if( (int)dNum2 == 0 ) { dResult = 0.0; break; } dResult = dNum1 / dNum2; } break; } returnString.valueOf(dResult); }完善Arithmetic類的run方法
在Arithmetic類run方法循環體中增加算式語法掃描、計算算式、輸出計算結果的代碼。
publicvoidrun(){ /** * 初始化help,并顯示help */ String strHelp = "***歡迎使用四則運算器***\n" + "算式計算:輸入算式后,按下回車鍵,程序給出答案。算式僅限于算式僅支持包含單個運算符和兩個整數運算數的算式。例如:15+20、8*9、20/5等。\n" + "退出程序:請輸入“quit”命令,按下回車鍵。" + "查看幫助:請輸入“help”命令,按下回車鍵。"; setHelp(strHelp); showHelp(); /** * 循環等待用戶輸入 */ //聲明Scanner變量,并用new運算符實例化Scanner Scanner sc = new Scanner(System.in); do { String strInput = sc.next(); //判斷用戶輸入內容,執行不同分支程序 if( strInput.equals("quit") ) quit(); elseif( strInput.equals("help") ) showHelp(); else { setFormula(strInput); //語法掃描 String ret = scanFormula(); //語法正確 if( ret.equals("sucess") ) { ret = calculateFormula(); printResult(ret); } else { //輸出語法錯誤信息 printResult(ret); } } }while(true); }至此,程序編寫完成。
總結
以上是生活随笔為你收集整理的Java项目开发全流程实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三子棋の胜负判断(洛谷P1838题题解,
- 下一篇: 贪心策略构筑“奶牛铁塔”(洛谷P2676