版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
揚(yáng)帆起航圈復(fù)雜度CyclomaticComplexityis17(maxallowedis7).CyclomaticComplexityisX(maxallowedisX)hongliangpan@
我的QQ:28797575知道做什么嗎?文檔示例無目錄有目錄不聚焦不知道目標(biāo),不知道總體結(jié)構(gòu)不知道是否合理沒有層次是否有遺漏帶來時(shí)間成本質(zhì)量問題4知道做什么嗎?圈復(fù)雜度概念概念計(jì)算方法檢查工具二不二重構(gòu)方法案例分析McCabe復(fù)雜度圈復(fù)雜度基本復(fù)雜度模塊設(shè)計(jì)復(fù)雜度設(shè)計(jì)復(fù)雜度集成復(fù)雜度行數(shù)全局?jǐn)?shù)據(jù)復(fù)雜度局部數(shù)據(jù)復(fù)雜度病態(tài)數(shù)據(jù)復(fù)雜度規(guī)范化復(fù)雜度框架群:181124238我的QQ:307087558(1)圈復(fù)雜度(CyclomaticComplexity(v(G)))概念圈復(fù)雜度是用來衡量一個(gè)模塊判定結(jié)構(gòu)的復(fù)雜程度,數(shù)量上表現(xiàn)為獨(dú)立路徑的條數(shù)。計(jì)算方法如果一個(gè)模塊流程圖有e條邊n個(gè)節(jié)點(diǎn),它的圈復(fù)雜度v(G)=e-n+2。
圈復(fù)雜度(CyclomaticComplexity)是一種代碼復(fù)雜度的衡量標(biāo)準(zhǔn)。它可以用來衡量一個(gè)模塊判定結(jié)構(gòu)的復(fù)雜程度,數(shù)量上表現(xiàn)為獨(dú)立線性路徑條數(shù),也可理解為覆蓋所有的可能情況最少使用的測(cè)試用例數(shù)。圈復(fù)雜度大說明程序代碼的判斷邏輯復(fù)雜,可能質(zhì)量低且難于測(cè)試和維護(hù)。程序的可能錯(cuò)誤和高的圈復(fù)雜度有著很大關(guān)系。
圈復(fù)雜度主要與分支語句(if、else、switch、for等)的個(gè)數(shù)成正相關(guān)。當(dāng)一段代碼中含有較多的分支語句,其邏輯復(fù)雜程度就會(huì)增加。什么是圈復(fù)雜度示例下面這個(gè)實(shí)例中,單元測(cè)試的覆蓋率可以達(dá)到100%,但是很容易發(fā)現(xiàn)這其中已經(jīng)漏掉了一個(gè)NPE的測(cè)試用例。case1方法的圈復(fù)雜度為2,因此至少需要2個(gè)用例才能完全覆蓋到其所有的可能情況。//程序原代碼,圈復(fù)雜度為2
publicStringcase1(intnum){
Stringstring=null;
if(num==1){
string="String";
}
returnstring.substring(0);
}//上面代碼的單元測(cè)試代碼
publicvoidtestCase1(){
Stringtest1=case1(1);
}
圈復(fù)雜度主要與分支語句(if、else、,switch等)的個(gè)數(shù)成正相關(guān)。當(dāng)一段代碼中含有較多的分支語句,其邏輯復(fù)雜程度就會(huì)增加。圈復(fù)雜度計(jì)算概念計(jì)算方法檢查工具二不二重構(gòu)方法案例分析示例如果一個(gè)模塊流程如下有e條邊n個(gè)節(jié)點(diǎn),它的圈復(fù)雜度v(G)=e-n+2例:
圈復(fù)雜度的計(jì)算
圈復(fù)雜度(cyclomaticcomplexity):M=E?N+2P
E:邊的數(shù)量
N:節(jié)點(diǎn)的數(shù)量
P:分離部分的數(shù)量,一般為1,都是聯(lián)通的
圈數(shù)(cyclomaticnumber):M=E?N+P
E,N,P參數(shù)同上
圈復(fù)雜度和圈數(shù)之間的關(guān)系為:
對(duì)有向圖A,將A的每個(gè)出口(exit)與相應(yīng)的入口(entrance)相連得到有向圖B,則A的圈復(fù)雜度與B的圈數(shù)相等
圈復(fù)雜度又叫做CC復(fù)雜度,也可能被稱為循環(huán)復(fù)雜度,它表達(dá)的是if..then..else..,swith..case..,循環(huán)語句等分支語句造成的程序控制流復(fù)雜程度
計(jì)算公式補(bǔ)充通常使用的計(jì)算公式是V(G)=e–n+2,e
代表在控制流圖中的邊的數(shù)量(對(duì)應(yīng)代碼中順序結(jié)構(gòu)的部分),n
代表在控制流圖中的節(jié)點(diǎn)數(shù)量,包括起點(diǎn)和終點(diǎn)(1、所有終點(diǎn)只計(jì)算一次,即便有多個(gè)return或者throw;2、節(jié)點(diǎn)對(duì)應(yīng)代碼中的分支語句)。例如下圖示例一個(gè)單入口、單出口的程序圖(不是結(jié)構(gòu)化程序圖),其圈復(fù)雜度為10-7+2=5:從節(jié)點(diǎn)G到A添加一條有向邊,則成為一個(gè)強(qiáng)連通有向圖(該方法對(duì)其它結(jié)構(gòu)化程序圖同樣適用),其圈數(shù)為11-7+1=5,與上圖的圈復(fù)雜度相同:計(jì)算示例
public
Stringcase2(int
index,Stringstring){
StringreturnString=
null;
if
(index<0){
throw
new
IndexOutOfBoundsException("exception<0");
}
if
(index==1){
if
(string.length()<2){
return
string;
}
returnString=
"returnString1";
}
else
if
(index==2){
if
(string.length()<5){
return
string;
}
returnString=
"returnString2";
}
else
{
throw
new
IndexOutOfBoundsException("exception>2");
}
return
returnString;
}根據(jù)公式
V(G)=e–n+2=12–8+2=6
。case2的圈復(fù)雜段為6。說明一下為什么n=8,雖然圖上的真正節(jié)點(diǎn)有12個(gè),但是其中有5個(gè)節(jié)點(diǎn)為throw、return,這樣的節(jié)點(diǎn)為end節(jié)點(diǎn),只能記做一個(gè)。計(jì)算示例檢查工具概念計(jì)算檢查工具二不二重構(gòu)檢查工具開發(fā)中常用的檢測(cè)圈復(fù)雜度的工具,PMD,checkstyle都可以檢測(cè)到高復(fù)雜度的代碼塊SourceMonitorEclipseMetric插件:有效地查出復(fù)雜度JavaNCSSNCSS表示NonCommentingSourceStatements工具目的Eclipse插件的URLCheckStyle編碼標(biāo)準(zhǔn)分析/update/Coverlipse測(cè)試代碼覆蓋率/updateCPD復(fù)制/粘貼檢驗(yàn)/eclipse/JDepend包依賴項(xiàng)分析http://andrei.gmxhome.de/eclipse/Metrics復(fù)雜度監(jiān)控/update7±2原則概念計(jì)算方法檢查工具二不二重構(gòu)方法案例分析直接管好幾百人女:有三室兩廳嗎?男:沒有女:有路虎,奧迪嗎?男:沒有!女:有7位數(shù)存款嗎(?男:沒有+!女:那你有啥?男:我………女轉(zhuǎn)身就走,。突然男的說:我管理幾百人(。。。女立刻回頭抱住男的腰,滿臉崇拜的說道:死鬼,你不早說,這就夠了?。。∧鞘鞘裁垂靖邔??男:我是群主群主燒鍋爐翻樣中國版主7±2原則如果你二,你就關(guān)注7+2件及以上事情【二貨九個(gè)圈】如果你不二,你就關(guān)注7-2件及以下事情【不二五個(gè)圈】圈復(fù)雜度高的,可以重構(gòu)為如:1.參數(shù)判斷2.取數(shù)據(jù)3.數(shù)據(jù)預(yù)處理4.數(shù)據(jù)轉(zhuǎn)換5.返回?cái)?shù)據(jù)
每一步可以是一個(gè)獨(dú)立的方法這樣主干邏輯非常的清晰,也就不二金字塔原理:有目標(biāo)、有層次、有順序總分總結(jié)構(gòu)把大象放冰箱里,統(tǒng)共分幾步?代碼大全25知道做什么嗎?26總共分5步評(píng)審、會(huì)議常見問題27如果去掉第二層圈復(fù)雜度是。。寫文檔沒有目錄大綱模塊設(shè)計(jì):一個(gè)包下N多個(gè)類代碼:超大方法超大類圈復(fù)雜度的重構(gòu)控制圈復(fù)雜度的N種重構(gòu)技術(shù)Refactoring:ImprovingtheDesignofExistingCode概念計(jì)算方法檢查工具二不二重構(gòu)方法案例分析金字塔原理總分總結(jié)構(gòu)把大象放冰箱里,統(tǒng)共分幾步?金字塔原理寫代碼和寫文章、畫畫總分總結(jié)構(gòu)把大象放冰箱里,統(tǒng)共分幾步?業(yè)務(wù)重構(gòu)架構(gòu)重構(gòu)設(shè)計(jì)重構(gòu)代碼重構(gòu)重復(fù)。代碼重復(fù)、結(jié)構(gòu)重復(fù)、邏輯重復(fù)。重復(fù)的代碼是抽象不夠的表現(xiàn)。如果是一個(gè)獨(dú)立完整的概念,可以提取成一個(gè)子程序(抽象)。舉例:多處的排序算法。冗長子程序。如果把子程序的一部分提取來作為另一個(gè)獨(dú)立的子程序,可以讓代碼更清晰,就提取成子程序。循環(huán)過長或嵌套過深。循環(huán)內(nèi)部的復(fù)雜代碼往往可以轉(zhuǎn)換成子程序。嵌套過深可以用前面“語句”中提過的方法解決。子程序命名不當(dāng)。需要子程序重命名,或合并、拆分子程序。難懂、拙劣的代碼。需要重整邏輯和流程?!a重構(gòu)重構(gòu)、金字塔原理降低圈復(fù)雜度的方法——重構(gòu)概念重構(gòu)(Refactoring)就是在不改變軟件現(xiàn)有功能的基礎(chǔ)上,通過調(diào)整程序代碼改善軟件的質(zhì)量、性能,使其程序的設(shè)計(jì)模式和架構(gòu)更趨合理,提高軟件的擴(kuò)展性和維護(hù)性。重構(gòu)方法重復(fù)代碼或者相似代碼提取為一個(gè)新的方法將過長的方法按功能拆分成小的方法將過大類的功能拆分成多個(gè)功能單一的小類推薦書籍《重構(gòu)——改善既有代碼的設(shè)計(jì)》作者:MartinFowler書中列出了長達(dá)70條的重構(gòu)名錄,提供了具體重構(gòu)的方法和重構(gòu)的技巧。將幫助開發(fā)人員一次一小步地修改代碼,減少了開發(fā)過程中的風(fēng)險(xiǎn)。Page32可以直接降低圈復(fù)雜度的10種重構(gòu)技術(shù)針對(duì)結(jié)構(gòu)化編程:ComposingMethods(重新組織你的函數(shù)) 1.ExtractMethod(提煉函數(shù)) 2.SubstituteAlgorithm(替換你的算法)SimplifyingConditionalExpressions(簡(jiǎn)化條件表達(dá)式) 3.DecomposeConditional(分解條件式)
4.ConsolidateConditionalExpression(合并條件式)
5.ConsolidateDuplicateConditionalFragments(合并重復(fù)的條件片斷) 6.RemoveControlFlag(移除控制標(biāo)記)MakingMethodCallsSimpler(簡(jiǎn)化函數(shù)調(diào)用) 7.SeparateQueryfromModifier(將查詢函數(shù)和修改函數(shù)分離) 8.ParameterizeMethod(令函數(shù)攜帶參數(shù)) 9.ReplaceParameterwithExplicitMethods(以明確函數(shù)取代參數(shù))
Refactoring:ImprovingtheDesignofExistingCode針對(duì)面向?qū)ο缶幊蹋?/p>
10.ReplaceConditionalwithPolymorphism(以多態(tài)取代條件式)控制圈復(fù)雜度的10種重構(gòu)技術(shù)總結(jié)可以直接降低圈復(fù)雜度的9種重構(gòu)技術(shù)(針對(duì)結(jié)構(gòu)化編程):*一、ComposingMethods(重新組織你的函數(shù))
1.Extract
Method(提煉函數(shù))
分為不同的step步驟進(jìn)行處理,主干邏輯方法控制在7個(gè)以內(nèi)
將代碼放進(jìn)一個(gè)獨(dú)立函數(shù)中,并讓函數(shù)名稱解釋該函數(shù)的用途
2.Substitute
Algorithm(替換你的算法)將函數(shù)本體替換為另一個(gè)更清晰、簡(jiǎn)化的算法,如多值匹配candidates.contains*二、SimplifyingConditionalExpressions(簡(jiǎn)化條件表達(dá)式)
3.Decompose
Conditional(分解條件式)
從if、then、else三個(gè)段落中分別提煉出獨(dú)立函數(shù)
4.Consolidate
ConditionalExpression(合并條件式)
將多個(gè)條件合并為c1||c2&&c3,并提煉為一個(gè)函數(shù)
5.Consolidate
DuplicateConditionalFragments(合并重復(fù)的條件片斷)
多個(gè)條件都執(zhí)行的代碼,將重復(fù)代碼搬移到條件式之外
6.Remove
ControlFlag(移除控制標(biāo)記)
以break和return取代控制標(biāo)記
*四、針對(duì)面向?qū)ο缶幊蹋?/p>
10.Replace
ConditionalwithPolymorphism(以多態(tài)取代條件式)
將整個(gè)條件式的每個(gè)分支放進(jìn)一個(gè)子類的重載方法中,然后將原始函數(shù)聲明為抽象方法
面向接口編程,一個(gè)接口多種實(shí)現(xiàn);利用state模式減少分支*三、MakingMethodCallsSimpler(簡(jiǎn)化函數(shù)調(diào)用)
7.Separate
QueryfromModifier(將查詢函數(shù)和修改函數(shù)分離)
單一職責(zé)原則,建立兩個(gè)不同的函數(shù),其中一個(gè)負(fù)責(zé)查詢,另一個(gè)負(fù)責(zé)修改
8.Parameterize
Method(令函數(shù)攜帶參數(shù))
通用函數(shù),建立單一函數(shù),以參數(shù)表達(dá)那些不同的值
9.Replace
ParameterwithExplicitMethods(以明確函數(shù)取代參數(shù))
多個(gè)if對(duì)應(yīng)對(duì)個(gè)函數(shù);
針對(duì)該參數(shù)的每一個(gè)可能值,建立一個(gè)獨(dú)立函數(shù)
Refactoring:ImprovingtheDesignofExistingCodePage34ExtractMethod(提煉函數(shù))voidprintOwing(doublepreviousAmount){Enumeratione=_orders.elements();doubleoutstanding=previousAmount*1.2;
//printbannerSystem.out.println("**************************");System.out.println("*****CustomerOwes******");System.out.println("**************************");//calculateoutstandingwhile(e.hasMoreElements()){Ordereach=(Order)e.nextElement();outstanding+=each.getAmount();}//printdetailsSystem.out.println("name:"+_name);System.out.println("amount"+outstanding);}voidprintOwing(doublepreviousAmount){printBanner();doubleoutstanding=getOutstanding(previousAmount*1.2);printDetails(outstanding);}voidprintBanner(){//printbannerSystem.out.println("**************************");System.out.println("*****CustomerOwes******");}doublegetOutstanding(doubleinitialValue){doubleresult=initialValue;Enumeratione=_orders.elements();while(e.hasMoreElements()){Ordereach=(Order)e.nextElement();result+=each.getAmount();}returnresult;}voidprintDetails(doubleoutstanding){System.out.println("name:"+_name);System.out.println("amount"+outstanding);}將這段代碼放進(jìn)一個(gè)獨(dú)立函數(shù)中,并讓函數(shù)名稱解釋該函數(shù)的用途你有一段代碼可以被組織在一起并獨(dú)立出來Page35SubstituteAlgorithm(替換你的算法)StringfoundPerson(String[]people){for(inti=0;i<people.length;i++){if(people[i].equals("Don"))return"Don";if(people[i].equals("John"))return"John";if(people[i].equals("Kent"))return"Kent";}return"";}StringfoundPerson(String[]people){Listcandidates=Arrays.asList(newString[]{"Don","John","Kent"});for(inti=0;i<people.length;i++)if(candidates.contains(people[i]))returnpeople[i];return"";}你想要把某個(gè)算法替換為另一個(gè)更清晰的算法將函數(shù)本體替換為另一個(gè)算法多值判斷用集合多個(gè)key,用map【當(dāng)這個(gè)值,調(diào)用某個(gè)服務(wù)】多值判斷用集合Page36DecomposeConditional(分解條件式)if(date.before(SUMMER_START)||date.after(SUMMER_END))charge=quantity*_winterRate+_winterServiceCharge;elsecharge=quantity*_summerRate;if(notSummer(date))charge=winterCharge(quantity);elsecharge=summerCharge(quantity);你有一個(gè)復(fù)雜的條件語句從if、then、else三個(gè)段落中分別提煉出獨(dú)立函數(shù)專注、聚焦Page37ConsolidateConditionalExpression(合并條件式)doubledisabilityAmount(){if(_seniority<2)return0;if(_monthsDisabled>12)return0;if(_isPartTime)return0;//computethedisabilityamountdoubledisabilityAmount(){if(isNotEligableForDisability())return0;//computethedisabilityamount將這些判斷合并為一個(gè)條件式,并將這個(gè)條件式提煉成為一個(gè)獨(dú)立函數(shù)你有一系列條件判斷,都得到相同結(jié)果Page38ConsolidateDuplicateConditionalFragments(合并重復(fù)的條件片斷)if(isSpecialDeal()){total=price*0.95;send();}else{total=price*0.98;send();}if(isSpecialDeal())total=price*0.95;elsetotal=price*0.98;send();在條件式的每個(gè)分支上有著相同的一段代碼。將這段重復(fù)代碼搬移到條件式之外反CVS模式Page39RemoveControlFlag(移除控制標(biāo)記)voidcheckSecurity(String[]people){booleanfound=false;for(inti=0;i<people.length;i++){if(!found){if(people[i].equals("Don")){sendAlert();found=true;}if(people[i].equals("John")){sendAlert();found=true;}}}}voidcheckSecurity(String[]people){for(inti=0;i<people.length;i++){if(people[i].equals("Don")){sendAlert();break;}if(people[i].equals("John")){sendAlert();break;}}}在一系列布爾表達(dá)式種,某個(gè)變量帶有【控制標(biāo)記】的作用以break和return取代控制標(biāo)記Page40SeparateQueryfromModifier(將查詢函數(shù)和修改函數(shù)分離)某個(gè)函數(shù)既返回對(duì)象狀態(tài)值,又修改對(duì)象狀態(tài)建立兩個(gè)不同的函數(shù),其中一個(gè)負(fù)責(zé)查詢,另一個(gè)負(fù)責(zé)修改CustomergetTotalOutstandingAndSetReadyForSummariesCustomergetTotalOutstandingSetReadyForSummaries反一心二用、左右互搏Page41ParameterizeMethod(令函數(shù)攜帶參數(shù))DollarsbaseCharge(){doubleresult=Math.min(lastUsage(),100)*0.03;if(lastUsage()>100){result+=(Math.min(lastUsage(),200)-100)*0.05;};if(lastUsage()>200){result+=(lastUsage()-200)*0.07;};returnnewDollars(result);}DollarsbaseCharge(){doubleresult=usageInRange(0,100)*0.03;result+=usageInRange(100,200)*0.05;result+=usageInRange(200,Integer.MAX_VALUE)*0.07;returnnewDollars(result);}intusageInRange(intstart,intend){if(lastUsage()>start)returnMath.min(lastUsage(),end)-start;elsereturn0;}若干函數(shù)做了類似的工作,但在函數(shù)本體中卻包含了不同的值建立單一函數(shù),以參數(shù)表達(dá)那些不同的值重構(gòu)為多參函數(shù)Page42ReplaceParameterwithExplicitMethods(以明確函數(shù)取代參數(shù))
voidsetValue(Stringname,intvalue){if(name.equals("height"))_height=value;if(name.equals("width"))_width=value;Assert.shouldNeverReachHere();}voidsetHeight(intarg){_height=arg;}voidsetWidth(intarg){_width=arg;}函數(shù)實(shí)現(xiàn)完全取決于參數(shù)值而采取不同反應(yīng)針對(duì)該參數(shù)的每一個(gè)可能值,建立一個(gè)獨(dú)立函數(shù)Page43ReplaceConditionalwithPolymorphism(以多態(tài)取代條件式)
doublegetSpeed(){switch(_type){caseEUROPEAN:returngetBaseSpeed();caseAFRICAN:returngetBaseSpeed()-getLoadFactor()*_numberOfCoconuts;caseNORWEGIAN_BLUE:return(_isNailed)?0:getBaseSpeed(_voltage);}thrownewRuntimeException("Shouldbeunreachable");}你手上有個(gè)條件式,它根據(jù)對(duì)象類型的不同而選擇不同的行為將整個(gè)條件式的每個(gè)分支放進(jìn)一個(gè)子類的重載方法中,然后將原始函數(shù)聲明為抽象方法面向接口編程利用state模式減少分支
劉翔有三種狀態(tài)三種狀態(tài),生病狀態(tài),正常狀態(tài),興奮狀態(tài)publicvoidrun(){if(state==NORMAL_STATE){//正常狀態(tài)下跑
System.out.println("100米,跑完共用時(shí)15秒!");}
elseif(state==MALUM_STATE){//生病狀態(tài)下跑System.out.println("100米,跑完共用時(shí)20秒!");
}
elseif(state==EXCITED_STATE){//興奮狀態(tài)下跑
System.out.println("100米,跑完共用時(shí)10秒!");}else{System.out.println("未知的狀態(tài)");}}publicinterfaceIState{publicvoiddoRun();}publicclassExcitedStateimplementsIState{publicvoiddoRun(){
System.out.println("100米,跑完共用時(shí)10鈔!");}}publicclassMalumStateimplementsIState{
publicvoiddoRun(){System.out.println("100米,跑完共用時(shí)20秒!");}}publicclassNormalStateimplementsIState{
publicvoiddoRun(){System.out.println("100米,跑完共用時(shí)15秒!");}}采用狀態(tài)模式的運(yùn)動(dòng)員publicclassGamer{//當(dāng)前狀態(tài)
privateIStatestate=newNormalState();//改變狀態(tài)的方法
publicvoidsetState(IStatestate){this.state=state;}//狀態(tài)行為方法,同上面的Gamer類相比這里沒有if..elseif判斷
publicvoidrun(){state.doRun();}}利用state模式減少分支
public
static
void
main(String[]
args)
{
//沒有使用狀態(tài)設(shè)計(jì)模式
com.bill99.pattern.Gamer
game
=
new
com.bill99.pattern.Gamer();
game.setState(0);
game.run();
game.setState(1);
game.run();
game.setState(2);
game.run();
System.out.println("");
//使用狀態(tài)設(shè)計(jì)模式
//正常狀態(tài)下跑
Gamer
gamer
=
new
Gamer();
gamer.run();
//生病狀態(tài)下跑
gamer.setState(new
MalumState());
gamer.run();
//興奮狀態(tài)下跑
gamer.setState(new
ExcitedState());
gamer.run();
}
SuperExcitedState假如我們?cè)贁U(kuò)展一個(gè)超級(jí)興奮的狀態(tài)SuperExcitedState,只需實(shí)現(xiàn)IState接口,定義好該狀態(tài)的行為,調(diào)用如下gamer.setState(new
SuperExcitedState());gamer.run();如果以后維護(hù)的話,要再加一個(gè)超級(jí)興奮的狀態(tài),得要改原來的源代碼,添加一個(gè)代表超級(jí)興奮的成員變量,再改if..elseif判斷,這樣做不符合OO設(shè)計(jì)原則,實(shí)現(xiàn)不了程序的松耦合??刂迫?fù)雜度的10種重構(gòu)技術(shù)總結(jié)可以直接降低圈復(fù)雜度的9種重構(gòu)技術(shù)(針對(duì)結(jié)構(gòu)化編程):*一、ComposingMethods(重新組織你的函數(shù))
1.Extract
Method(提煉函數(shù))
分為不同的step步驟進(jìn)行處理,主干邏輯方法控制在7個(gè)以內(nèi)
將代碼放進(jìn)一個(gè)獨(dú)立函數(shù)中,并讓函數(shù)名稱解釋該函數(shù)的用途
2.Substitute
Algorithm(替換你的算法)將函數(shù)本體替換為另一個(gè)更清晰、簡(jiǎn)化的算法,如多值匹配candidates.contains*二、SimplifyingConditionalExpressions(簡(jiǎn)化條件表達(dá)式)
3.Decompose
Conditional(分解條件式)
從if、then、else三個(gè)段落中分別提煉出獨(dú)立函數(shù)
4.Consolidate
ConditionalExpression(合并條件式)
將多個(gè)條件合并為c1||c2&&c3,并提煉為一個(gè)函數(shù)
5.Consolidate
DuplicateConditionalFragments(合并重復(fù)的條件片斷)
多個(gè)條件都執(zhí)行的代碼,將重復(fù)代碼搬移到條件式之外
6.Remove
ControlFlag(移除控制標(biāo)記)
以break和return取代控制標(biāo)記
*四、針對(duì)面向?qū)ο缶幊蹋?/p>
10.Replace
ConditionalwithPolymorphism(以多態(tài)取代條件式)
將整個(gè)條件式的每個(gè)分支放進(jìn)一個(gè)子類的重載方法中,然后將原始函數(shù)聲明為抽象方法
面向接口編程,一個(gè)接口多種實(shí)現(xiàn);利用state模式減少分支*三、MakingMethodCallsSimpler(簡(jiǎn)化函數(shù)調(diào)用)
7.Separate
QueryfromModifier(將查詢函數(shù)和修改函數(shù)分離)
單一職責(zé)原則,建立兩個(gè)不同的函數(shù),其中一個(gè)負(fù)責(zé)查詢,另一個(gè)負(fù)責(zé)修改
8.Parameterize
Method(令函數(shù)攜帶參數(shù))
通用函數(shù),建立單一函數(shù),以參數(shù)表達(dá)那些不同的值
9.Replace
ParameterwithExplicitMethods(以明確函數(shù)取代參數(shù))
多個(gè)if對(duì)應(yīng)對(duì)個(gè)函數(shù);
針對(duì)該參數(shù)的每一個(gè)可能值,建立一個(gè)獨(dú)立函數(shù)
Refactoring:ImprovingtheDesignofExistingCode重構(gòu)案例控制圈復(fù)雜度的N種重構(gòu)技術(shù)Refactoring:ImprovingtheDesignofExistingCode概念計(jì)算方法檢查工具二不二重構(gòu)方法案例分析代碼生成工具優(yōu)化重構(gòu)前重構(gòu)后1.生成參數(shù)信息2.生成文件內(nèi)容3.寫到文件4.打印日志混亂的代碼是混亂思維的產(chǎn)物上傳文件代碼示例1.不是excel,返回2.超過大小限制,返回3.不滿足條件,返回4.文件內(nèi)容校驗(yàn)5.多處String類型非空判斷if(StringUtil.isEmpty(username))thrownewICRClientException("usernamecannotbenull");if(StringUtil.isEmpty(password))thrownewICRClientException("passwordcannotbenull");if(udto==null)thrownewICRClientException("ICRUploadDTOcannotbenull");//將原來的地方替換為checkStringParamEmpty(username,"username");checkStringParamEmpty(password,"password");checkStringParamEmpty(udto.getUrlPath(),"urlPath");...//新增一個(gè)方法privatevoidcheckStringParamEmpty(Stringvalue,Stringname)throwsICRClientException{if(StringUtil.isEmpty(value)){thrownewICRClientException(name+"cannotbenull");}}多String值判斷if(!udto.getPriority().equals("0")&&!udto.getPriority().equals("1")&&!udto.getPriority().equals("2")&&!udto.getPriority().equals("3"))thrownewICRClientException("prioritymustbe0/1/2/3");//將原來代碼替換為checkValueWithinList(udto.getPriority());...//新增一個(gè)方法:privatevoidcheckValueWithinList(Stringpriority)throwsICRClientException{if(!Arrays.asList("0","1","2","3").contains(priority)){thrownewICRClientException("prioritymustbe0/1/2/3");}}多個(gè)catch的內(nèi)容相同intcode=0;try{code=httpClient.executeMethod(post);}catch(HttpExceptione){thrownewICRClientException(e.getMessage(),e);}catch(IOExceptione){thrownewICRClientException(e.getMessage(),e);}//將原來的地方替換為intcode=executeHttpClient(httpClient,post);...//新增一個(gè)方法privateintexecuteHttpClient(HttpClienthttpClient,PostMethodpost)throwsICRClientException{intcode;try{code=httpClient.executeMethod(post);}catch(Exceptione){thrownewICRClientException(e.getMessage(),e);}returncode;}if判斷結(jié)果復(fù)雜化if(code==200){try{if(post.getResponseBodyAsString().equals("ok")){returntrue;}}catch(IOExceptione){thrownewICRClientException(e.getMessage(),e);}returnfalse;}elseif(code==500){thrownewICRClientException(post.getResponseBodyAsString());}else{thrownewICRClientException(code+":"+post.getStatusText());}returnreturnFinialResult(post,code);...//新增一個(gè)方法privatebooleanreturnFinialResult(PostMethodpost,intcode)throwsICRClientException,IOException{if(code==500)thrownewICRClientException(post.getResponseBodyAsString());if(code!=200)thrownewICRClientException(code+":"+post.getStatusText());try{returnpost.getResponseBodyAsString().equals("ok");}catch(IOExceptione){thrownewICRClientException(e.getMessage(),e);}}本地變量始終不為nullpublicbooleanuploadToICR(Stringusername,Stringpassword,ICRUploadDTOudto)throwsICRClientException{HttpClienthttpClient=null;PostMethodpost=null;httpClient=newHttpClient();//somecodehere…}finally{if(post!=null){post.releaseConnection();}if(httpClient!=null){httpClient.getHttpConnectionManager().closeIdleConnections(0);}}publicbooleanuploadToICR(Stringusername,Stringpassword,ICRUploadDTOudto)throwsICRClientException{HttpClienthttpClient=newHttpClient();PostMethodpost=null;//somecodehere…}finally{if(post!=null){post.releaseConnection();}}}讀取IO流的方法,為什么要自己實(shí)現(xiàn)?privatebyte[]readData(InputStreamins)throwsIOException{byte[]buf=newbyte[2048];intcount=0;intlen=0;bytedata[]=newbyte[2048];byte[]result=null;try{while((len=ins.read(data,0,2048))!=-1){intnewcount=count+len;if(newcount>buf.length){bytenewbuf[]=newbyte[Math.max(buf.length<<1,newcount)];System.arraycopy(buf,0,newbuf,0,count);buf=newbuf;}System.arraycopy(data,0,buf,count,len);count=newcount;}result=newbyte[count];System.arraycopy(buf,0,result,0,count);}finally{ins.close();}re
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度智能化農(nóng)業(yè)機(jī)械購置及售后服務(wù)合同范本4篇
- 二零二五年度「精英招募」企業(yè)人才招聘合同模板3篇
- 二零二五年度游戲角色設(shè)計(jì)授權(quán)合同4篇
- 2025年度房地產(chǎn)項(xiàng)目預(yù)售合同示范文本4篇
- 2025年度南匯農(nóng)業(yè)志修訂與版權(quán)登記合同3篇
- 二零二五版汽車維修連鎖店經(jīng)營權(quán)轉(zhuǎn)讓合同2篇
- 2025年度個(gè)人設(shè)備租賃擔(dān)保貸款合同范本2篇
- 2025年度苗木出口貿(mào)易合同標(biāo)準(zhǔn)樣本3篇
- 2025年度個(gè)人借款合同信用評(píng)估體系構(gòu)建4篇
- 二零二五年度新型建材門面房租賃及推廣合作合同
- 經(jīng)營范圍登記規(guī)范表述目錄(試行)(V1.0.2版)
- 阿里商旅整體差旅解決方案
- 浙江天臺(tái)歷史文化名城保護(hù)規(guī)劃說明書
- 邏輯思維訓(xùn)練500題
- 第八講 發(fā)展全過程人民民主PPT習(xí)概論2023優(yōu)化版教學(xué)課件
- 實(shí)體瘤療效評(píng)價(jià)標(biāo)準(zhǔn)RECIST-1.1版中文
- 企業(yè)新春茶話會(huì)PPT模板
- GB/T 19185-2008交流線路帶電作業(yè)安全距離計(jì)算方法
- DIC診治新進(jìn)展課件
- 公路工程施工現(xiàn)場(chǎng)安全檢查手冊(cè)
- 1汽輪機(jī)跳閘事故演練
評(píng)論
0/150
提交評(píng)論