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