




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、揚帆起航圈復(fù)雜度圈復(fù)雜度Cyclomatic Complexity is 17 (max allowed is 7).Cyclomatic Complexity is X (max allowed is X) 我的QQ:28797575知道做什么嗎?文檔示例 無目錄 有目錄不聚焦不知道目標(biāo),不知道總體結(jié)構(gòu)不知道是否合理沒有層次是否有遺漏帶來時間成本質(zhì)量問題4知道做什么嗎? QQ: 28797575圈復(fù)雜度 概念概念概念計算方法計算方法檢查工具檢查工具二二不不二二重構(gòu)方法重構(gòu)方法案例分析案例分析McCabe復(fù)雜度圈復(fù)雜度圈復(fù)雜度基本復(fù)雜度基本復(fù)雜度模塊設(shè)計復(fù)雜度模塊設(shè)計復(fù)雜度設(shè)計復(fù)雜度設(shè)計復(fù)雜度
2、集成復(fù)雜度集成復(fù)雜度行數(shù)行數(shù)全局?jǐn)?shù)據(jù)復(fù)雜度全局?jǐn)?shù)據(jù)復(fù)雜度局部數(shù)據(jù)復(fù)雜度局部數(shù)據(jù)復(fù)雜度病態(tài)數(shù)據(jù)復(fù)雜度病態(tài)數(shù)據(jù)復(fù)雜度規(guī)范化復(fù)雜度規(guī)范化復(fù)雜度框架群:181124238 我的QQ:307087558(1)圈復(fù)雜度(Cyclomatic Complexity (v(G) )l概念圈復(fù)雜度是用來衡量一個模塊判定結(jié)構(gòu)的復(fù)雜程度,數(shù)量上表現(xiàn)為獨立路徑的條數(shù)。l計算方法如果一個模塊流程圖有e條邊n個節(jié)點, 它的圈復(fù)雜度v(G)=e-n+2。 QQ: 28797575 圈復(fù)雜度(Cyclomatic Complexity)是一種代碼復(fù)雜度的衡量標(biāo)準(zhǔn)。它可以用來衡量一個模塊判定結(jié)構(gòu)的復(fù)雜程度,數(shù)量上表現(xiàn)為獨立線性
3、路徑條數(shù),也可理解為覆蓋所有的可能情況最少使用的測試用例數(shù)。圈復(fù)雜度大說明程序代碼的判斷邏輯復(fù)雜,可能質(zhì)量低且難于測試和維護(hù)。程序的可能錯誤和高的圈復(fù)雜度有著很大關(guān)系。 圈復(fù)雜度主要與分支語句(if、else、switch 、for等)的個數(shù)成正相關(guān)。當(dāng)一段代碼中含有較多的分支語句,其邏輯復(fù)雜程度就會增加。什么是圈復(fù)雜度 QQ: 28797575示例下面這個實例中,單元測試的覆蓋率可以達(dá)到100%,但是很容易發(fā)現(xiàn)這其中已經(jīng)漏掉了一個NPE的測試用例。case1方法的圈復(fù)雜度為2,因此至少需要2個用例才能完全覆蓋到其所有的可能情況。/程序原代碼,圈復(fù)雜度為 2public String case
4、1(int num) String string = null; if (num = 1) string = String; return string.substring(0);/上面代碼的單元測試代碼public void testCase1() String test1 = case1(1); 圈復(fù)雜度主要與分支語句(if、else、,switch 等)的個數(shù)成正相關(guān)。當(dāng)一段代碼中含有較多的分支語句,其邏輯復(fù)雜程度就會增加。 QQ: QQ: 28797575圈復(fù)雜度 計算概念概念計算方法計算方法檢查工具檢查工具二不二二不二重構(gòu)方法重構(gòu)方法案例分析案例分析 QQ: 28797575示例 如
5、果一個模塊流程如下有e條邊n個節(jié)點,它的圈復(fù)雜度v(G) = e-n+2 例: QQ: 28797575圈復(fù)雜度的計算 圈復(fù)雜度(cyclomatic complexity): M = E N + 2P E: 邊的數(shù)量 N: 節(jié)點的數(shù)量 P: 分離部分的數(shù)量,一般為1,都是聯(lián)通的 圈數(shù)(cyclomatic number): M = E N + P E,N,P參數(shù)同上 圈復(fù)雜度和圈數(shù)之間的關(guān)系為: 對有向圖A,將A的每個出口(exit)與相應(yīng)的入口(entrance)相連得到有向圖B,則A的圈復(fù)雜度與B的圈數(shù)相等 圈復(fù)雜度又叫做CC復(fù)雜度,也可能被稱為循環(huán)復(fù)雜度,它表達(dá)的是if . then
6、. else ., swith . case ., 循環(huán)語句等分支語句造成的程序控制流復(fù)雜程度 QQ: 28797575計算公式補(bǔ)充 通常使用的計算公式是V(G) = e n + 2 , e 代表在控制流圖中的邊的數(shù)量(對應(yīng)代碼中順序結(jié)構(gòu)的部分),n 代表在控制流圖中的節(jié)點數(shù)量,包括起點和終點(1、所有終點只計算一次,即便有多個return或者throw;2、節(jié)點對應(yīng)代碼中的分支語句)。 QQ: 28797575 例如下圖示例一個單入口、單出口的程序圖(不是結(jié)構(gòu)化程序圖),其圈復(fù)雜度為10-7+2=5: 從節(jié)點G到A添加一條有向邊,則成為一個強(qiáng)連通有向圖(該方法對其它結(jié)構(gòu)化程序圖同樣適用),其
7、圈數(shù)為11-7+1=5,與上圖的圈復(fù)雜度相同: QQ: 28797575計算示例 public String case2(int index, String string) String returnString = 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(
8、) 2 ); return returnString; QQ: 28797575 根據(jù)公式 V(G) = e n + 2 = 12 8 + 2 = 6 。case2的圈復(fù)雜段為6。說明一下為什么n = 8,雖然圖上的真正節(jié)點有12個,但是其中有5個節(jié)點為throw、return,這樣的節(jié)點為end節(jié)點,只能記做一個。計算示例檢查工具概念概念計算計算檢查工具檢查工具二二不不二二重構(gòu)重構(gòu) QQ: 28797575檢查工具 開發(fā)中常用的檢測圈復(fù)雜度的工具,PMD,checkstyle都可以檢測到高復(fù)雜度的代碼塊 Eclipse Metric 插件:有效地查出復(fù)雜度 JavaNCSS NCSS表示No
9、n Commenting Source S QQ: 28797575工具工具目的目的Eclipse 插件的插件的 URLCheckStyle編碼標(biāo)準(zhǔn)分析http:/eclipse- QQ: 28797575直接管好幾百人女:有三室兩廳嗎?男:沒有 女:有路虎,奧迪嗎? 男:沒有! 女:有7位數(shù)存款嗎(? 男:沒有+! 女:那你有啥? 男:我 女轉(zhuǎn)身就走,。 突然男的說:我管理幾百人(。 女立刻回頭抱住男的腰,滿臉崇拜的說道:死鬼,你不早說,這就夠了!那是什么公司高層? 男:我是群主群主燒鍋爐翻樣中國版主 QQ: 2879757572原則如果你二,你就關(guān)注7+2件及以上事情【二貨九個圈】如果你不
10、二,你就關(guān)注7-2件及以下事情【不二五個圈】圈復(fù)雜度高的,可以重構(gòu)為如:1.參數(shù)判斷2.取數(shù)據(jù)3.數(shù)據(jù)預(yù)處理4.數(shù)據(jù)轉(zhuǎn)換5.返回數(shù)據(jù)每一步可以是一個獨立的方法這樣主干邏輯非常的清晰,也就不二金字塔金字塔原理:有目標(biāo)、有層次、有順序原理:有目標(biāo)、有層次、有順序總分總結(jié)構(gòu)總分總結(jié)構(gòu)把大象放冰箱里,統(tǒng)共分幾步?把大象放冰箱里,統(tǒng)共分幾步? QQ: 28797575代碼大全25知道做什么嗎?26總總共共分分5步步評審、會議常見問題27如果去掉第二層如果去掉第二層圈復(fù)雜度是。圈復(fù)雜度是。 QQ: 28797575寫文檔沒有目錄大綱模塊設(shè)計:一個包下N多個類代碼:超大方法超大類圈復(fù)雜度的重構(gòu)控制圈復(fù)雜度的
11、N種重構(gòu)技術(shù)-Refactoring: Improving the Design of Existing Code概念概念計算方法計算方法檢查工具檢查工具二不二二不二重構(gòu)方法重構(gòu)方法案例分析案例分析金字塔原理金字塔原理總分總結(jié)構(gòu)總分總結(jié)構(gòu)把大象放冰箱里,統(tǒng)共分幾步?把大象放冰箱里,統(tǒng)共分幾步?金字塔原理金字塔原理 寫代碼和寫文章、畫畫寫代碼和寫文章、畫畫總分總結(jié)構(gòu)總分總結(jié)構(gòu)把大象放冰箱里,統(tǒng)共分幾步?把大象放冰箱里,統(tǒng)共分幾步?業(yè)務(wù)重構(gòu)業(yè)務(wù)重構(gòu)架構(gòu)重構(gòu)架構(gòu)重構(gòu)設(shè)計重構(gòu)設(shè)計重構(gòu)代碼重構(gòu)代碼重構(gòu)重復(fù)重復(fù)。代碼重復(fù)、結(jié)構(gòu)重復(fù)、邏輯重復(fù)。重復(fù)的代碼是抽象不夠的表現(xiàn)。如果是一個獨立完整的概念,可以提取成
12、一個子程序(抽象)。舉例:多處的排序算法。冗長子程序冗長子程序。如果把子程序的一部分提取來作為另一個獨立的子程序,可以讓代碼更清晰,就提取成子程序。循環(huán)過長或嵌套過深循環(huán)過長或嵌套過深。循環(huán)內(nèi)部的復(fù)雜代碼往往可以轉(zhuǎn)換成子程序。嵌套過深可以用前面“語句”中提過的方法解決。子程序命名不當(dāng)子程序命名不當(dāng)。需要子程序重命名,或合并、拆分子程序。難懂、拙劣的代碼難懂、拙劣的代碼。需要重整邏輯和流程。代碼重構(gòu)代碼重構(gòu)降低圈復(fù)雜度的方法重構(gòu)l 概念 重構(gòu)(Refactoring)就是在不改變軟件現(xiàn)有功能的基礎(chǔ)上,通過調(diào)整程序代碼改善軟件的質(zhì)量、性能,使其程序的設(shè)計模式和架構(gòu)更趨合理,提高軟件的擴(kuò)展性和維護(hù)性
13、。l 重構(gòu)方法 重復(fù)代碼或者相似代碼提取為一個新的方法 將過長的方法按功能拆分成小的方法 將過大類的功能拆分成多個功能單一的小類l 推薦書籍 重構(gòu)改善既有代碼的設(shè)計 作者:Martin Fowler 書中列出了長達(dá)70條的重構(gòu)名錄,提供了具體重構(gòu)的方法和重構(gòu)的技巧。將幫助開發(fā)人員一次一小步地修改代碼,減少了開發(fā)過程中的風(fēng)險。 QQ: 28797575Page 32可以直接降低圈復(fù)雜度的10種重構(gòu)技術(shù)針對結(jié)構(gòu)化編程:Composing Methods(重新組織你的函數(shù))1.Extract Method(提煉函數(shù))2.Substitute Algorithm(替換你的算法)Simplifying
14、Conditional Expressions(簡化條件表達(dá)式)3.Decompose Conditional(分解條件式)4.Consolidate Conditional Expression(合并條件式)5.Consolidate Duplicate Conditional Fragments(合并重復(fù)的條件片斷)6.Remove Control Flag(移除控制標(biāo)記)Making Method Calls Simpler(簡化函數(shù)調(diào)用)7.Separate Query from Modifier(將查詢函數(shù)和修改函數(shù)分離)8.Parameterize Method(令函數(shù)攜帶參數(shù))9
15、.Replace Parameter with Explicit Methods(以明確函數(shù)取代參數(shù))- Refactoring: Improving the Design of Existing Code針對面向?qū)ο缶幊蹋?0.Replace Conditional with Polymorphism(以多態(tài)取代條件式)控制圈復(fù)雜度的10種重構(gòu)技術(shù)總結(jié)可以直接降低圈復(fù)雜度的9種重構(gòu)技術(shù)(針對結(jié)構(gòu)化編程):*一、Composing Methods(重新組織你的函數(shù)) 1.Extract Method(提煉函數(shù)) 分為不同的step步驟進(jìn)行處理,主干邏輯方法控制在7個以內(nèi) 將代碼放進(jìn)一個獨立函數(shù)
16、中,并讓函數(shù)名稱解釋該函數(shù)的用途 2.Substitute Algorithm(替換你的算法) 將函數(shù)本體替換為另一個更清晰、簡化的算法 ,如多值匹配 candidates.contains*二、Simplifying Conditional Expressions(簡化條件表達(dá)式) 3.Decompose Conditional(分解條件式) 從if、then、else三個段落中分別提煉出獨立函數(shù) 4.Consolidate Conditional Expression(合并條件式) 將多個條件合并 為 c1|c2&c3,并提煉為一個函數(shù) 5.Consolidate Duplicat
17、e Conditional Fragments(合并重復(fù)的條件片斷) 多個條件都執(zhí)行的代碼,將重復(fù)代碼搬移到條件式之外 6.Remove Control Flag(移除控制標(biāo)記) 以break和return取代控制標(biāo)記* 10.Replace Conditional with Polymorphism(以多態(tài)?。ㄒ远鄳B(tài)取代條件式)代條件式) 將整個條件式的每個分支放進(jìn)一個子類的重載方法將整個條件式的每個分支放進(jìn)一個子類的重載方法中,然后將原始函數(shù)聲明為抽象方法中,然后將原始函數(shù)聲明為抽象方法 面向接口編程,一個接口多種實現(xiàn);利用state模式減少分支*三三、Making Method Call
18、s Simpler(簡化函數(shù)調(diào)用)(簡化函數(shù)調(diào)用) 7.Separate Query from Modifier(將查詢函數(shù)和修改函數(shù)分(將查詢函數(shù)和修改函數(shù)分離)離) 單一職責(zé)原則,建立兩個不同的函數(shù),其中一個負(fù)責(zé)查建立兩個不同的函數(shù),其中一個負(fù)責(zé)查詢,另一個負(fù)責(zé)修改詢,另一個負(fù)責(zé)修改 8.Parameterize Method(令函數(shù)攜帶參數(shù))(令函數(shù)攜帶參數(shù)) 通用函數(shù),建立單一函數(shù),以參數(shù)表達(dá)那些不同的值建立單一函數(shù),以參數(shù)表達(dá)那些不同的值 9.Replace Parameter with Explicit Methods(以明確函數(shù)取(以明確函數(shù)取代參數(shù))代參數(shù)) 多個if對應(yīng)對個函
19、數(shù); 針對該參數(shù)的每一個可能值,建立針對該參數(shù)的每一個可能值,建立一個獨立函數(shù)一個獨立函數(shù) - Refactoring: Improving the Design of Existing CodePage 34Extract Method(提煉函數(shù))void printOwing(double previousAmount) Enumeration e = _orders.elements(); double outstanding = previousAmount * 1.2; / print banner System.out.println (*); System.out.println
20、 (* Customer Owes *); System.out.println (*); / calculate outstanding while (e.hasMoreElements() Order each = (Order) e.nextElement(); outstanding += each.getAmount(); /print details System.out.println (name: + _name); System.out.println (amount + outstanding);void printOwing(double previousAmount)
21、printBanner(); double outstanding = getOutstanding(previousAmount * 1.2); printDetails(outstanding);void printBanner() / print banner System.out.println (*); System.out.println (* Customer Owes *);double getOutstanding(double initialValue) double result = initialValue; Enumeration e = _orders.elemen
22、ts(); while (e.hasMoreElements() Order each = (Order) e.nextElement(); result += each.getAmount(); return result;void printDetails (double outstanding) System.out.println (name: + _name); System.out.println (amount + outstanding);將這段代碼放進(jìn)一個獨立函數(shù)中,將這段代碼放進(jìn)一個獨立函數(shù)中,并讓函數(shù)名稱解釋該函數(shù)的用途并讓函數(shù)名稱解釋該函數(shù)的用途你有一段代碼可以被組織在
23、一起并獨立出來Page 35Substitute Algorithm(替換你的算法)String foundPerson(String people) for (int i = 0; i people.length; i+) if (peoplei.equals (Don) return Don; if (peoplei.equals (John) return John; if (peoplei.equals (Kent) return Kent; return ;String foundPerson(String people) List candidates = Arrays.asLis
24、t(new StringDon, John,Kent); for (int i=0; ipeople.length; i+) if (candidates.contains(peoplei) return peoplei; return ;你想要把某個算法替換為另一個更清晰的算法將函數(shù)本體替換為另一個算法多值判斷用集合多個key,用map【當(dāng)這個值,調(diào)用某個服務(wù)】多值判斷用集合Page 36Decompose Conditional(分解條件式)if (date.before (SUMMER_START) | date.after(SUMMER_END) charge = quantity *
25、 _winterRate + _winterServiceCharge;else charge = quantity * _summerRate;if (notSummer(date) charge = winterCharge(quantity);else charge = summerCharge (quantity);你有一個復(fù)雜的條件語句從從if、then、else三個段落中分別提煉出獨立函數(shù)三個段落中分別提煉出獨立函數(shù)專注、聚焦專注、聚焦Page 37Consolidate Conditional Expression(合并條件式)double disabilityAmount()
26、if (_seniority 12) return 0; if (_isPartTime) return 0; / compute the disability amountdouble disabilityAmount() if (isNotEligableForDisability() return 0; / compute the disability amount將這些判斷合并為一個條件式,并將這個條件式提煉成為一個獨立函數(shù)將這些判斷合并為一個條件式,并將這個條件式提煉成為一個獨立函數(shù)你有一系列條件判斷,都得到相同結(jié)果Page 38Consolidate Duplicate Condi
27、tional Fragments(合并重復(fù)的條件片斷)if (isSpecialDeal() total = price * 0.95; send(); else total = price * 0.98; send(); if (isSpecialDeal() total = price * 0.95;else total = price * 0.98;send();在條件式的每個分支上有著相同的一段代碼。將這段重復(fù)代碼搬移到條件式之外將這段重復(fù)代碼搬移到條件式之外反反CVS模式模式Page 39Remove Control Flag(移除控制標(biāo)記)void checkSecurity(St
28、ring people) boolean found = false; for (int i = 0; i people.length; i+) if (! found) if (peoplei.equals (Don) sendAlert(); found = true; if (peoplei.equals (John) sendAlert(); found = true; void checkSecurity(String people) for (int i = 0; i 100) result += (Math.min (lastUsage(),200) - 100) * 0.05;
29、 ; if (lastUsage() 200) result += (lastUsage() - 200) * 0.07; ; return new Dollars (result);Dollars baseCharge() double result = usageInRange(0, 100) * 0.03; result += usageInRange (100,200) * 0.05; result += usageInRange (200, Integer.MAX_VALUE) * 0.07; return new Dollars (result);int usageInRange(
30、int start, int end) if (lastUsage() start) return Math.min(lastUsage(),end) -start; else return 0;若干函數(shù)做了類似的工作,但在函數(shù)本體中卻包含了不同的值建立單一函數(shù),以參數(shù)表達(dá)那些不同的值建立單一函數(shù),以參數(shù)表達(dá)那些不同的值重構(gòu)為多參函數(shù)重構(gòu)為多參函數(shù)Page 42Replace Parameter with Explicit Methods(以明確函數(shù)取代參數(shù))void setValue (String name, int value) if (name.equals(height) _heig
31、ht = value; if (name.equals(width) _width = value; Assert.shouldNeverReachHere();void setHeight(int arg) _height = arg;void setWidth (int arg) _width = arg;函數(shù)實現(xiàn)完全取決于參數(shù)值而采取不同反應(yīng)針對該參數(shù)的每一個可能值,建立一個獨立函數(shù)針對該參數(shù)的每一個可能值,建立一個獨立函數(shù)Page 43Replace Conditional with Polymorphism(以多態(tài)取代條件式)double getSpeed() switch (_ty
32、pe) case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() *_numberOfCoconuts; case NORWEGIAN_BLUE: return (_isNailed) ? 0 : getBaseSpeed(_voltage); throw new RuntimeException (Should be unreachable);你手上有個條件式,它根據(jù)對象類型的不同而選擇不同的行為將整個條件式的每個分支放進(jìn)一個子類的重載方法中,然后將原始函數(shù)聲明為抽象
33、方法將整個條件式的每個分支放進(jìn)一個子類的重載方法中,然后將原始函數(shù)聲明為抽象方法+getSpeed()BirdBird+getSpeed()EuropeanEuropean+getSpeed()AfricanAfrican+getSpeed()Norwegian BlueNorwegian Blue面向接口編程面向接口編程利用state模式減少分支 劉翔有三種狀態(tài)三種狀態(tài),生病狀態(tài),正常狀態(tài),興奮狀態(tài)public void run() if(state = NORMAL_STATE) /正常狀態(tài)下跑 System.out.println(100米,跑完共用時15秒!); else if(sta
34、te = MALUM_STATE) /生病狀態(tài)下跑 System.out.println(100米,跑完共用時20秒!); else if(state = EXCITED_STATE) /興奮狀態(tài)下跑 System.out.println(100米,跑完共用時10秒!); else System.out.println(未知的狀態(tài));public interface IState public void doRun(); public class ExcitedState implements IState public void doRun() System.out.println(100米
35、,跑完共用時10鈔!); public class MalumState implements IState public void doRun() System.out.println(100米,跑完共用時20秒!); public class NormalState implements IState public void doRun() System.out.println(100米,跑完共用時15秒!); 采用狀態(tài)模式的運動員public class Gamer /當(dāng)前狀態(tài) private IState state = new NormalState(); /改變狀態(tài)的方法 publ
36、ic void setState(IState state) this.state = state; /狀態(tài)行為方法,同上面的Gamer 類相比這里沒有if.else if判斷 public void run() state.doRun(); 利用state模式減少分支 public static void main(String args) /沒有使用狀態(tài)設(shè)計模式 com.bill99.pattern.Gamer game = new com.bill99.pattern.Gamer(); game.setState(0); game.run(); game.setState(1); gam
37、e.run(); game.setState(2); game.run(); System.out.println(-); /使用狀態(tài)設(shè)計模式 /正常狀態(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假如我們再擴(kuò)展一個超級興奮的狀態(tài)SuperExcitedState,只需實現(xiàn)IState接口,定義好該狀態(tài)
38、的行為,調(diào)用如下gamer.setState(new SuperExcitedState();gamer.run();如果以后維護(hù)的話,要再加一個超級興奮的狀態(tài),得要改原來的源代碼,添加一個代表超級興奮的成員變量,再改if.else if判斷,這樣做不符合OO設(shè)計原則,實現(xiàn)不了程序的松耦合??刂迫?fù)雜度的10種重構(gòu)技術(shù)總結(jié)可以直接降低圈復(fù)雜度的9種重構(gòu)技術(shù)(針對結(jié)構(gòu)化編程):*一、Composing Methods(重新組織你的函數(shù)) 1.Extract Method(提煉函數(shù)) 分為不同的step步驟進(jìn)行處理,主干邏輯方法控制在7個以內(nèi) 將代碼放進(jìn)一個獨立函數(shù)中,并讓函數(shù)名稱解釋該函數(shù)的用途
39、 2.Substitute Algorithm(替換你的算法) 將函數(shù)本體替換為另一個更清晰、簡化的算法 ,如多值匹配 candidates.contains*二、Simplifying Conditional Expressions(簡化條件表達(dá)式) 3.Decompose Conditional(分解條件式) 從if、then、else三個段落中分別提煉出獨立函數(shù) 4.Consolidate Conditional Expression(合并條件式) 將多個條件合并 為 c1|c2&c3,并提煉為一個函數(shù) 5.Consolidate Duplicate Conditional Fr
40、agments(合并重復(fù)的條件片斷) 多個條件都執(zhí)行的代碼,將重復(fù)代碼搬移到條件式之外 6.Remove Control Flag(移除控制標(biāo)記) 以break和return取代控制標(biāo)記* 10.Replace Conditional with Polymorphism(以多態(tài)?。ㄒ远鄳B(tài)取代條件式)代條件式) 將整個條件式的每個分支放進(jìn)一個子類的重載方法將整個條件式的每個分支放進(jìn)一個子類的重載方法中,然后將原始函數(shù)聲明為抽象方法中,然后將原始函數(shù)聲明為抽象方法 面向接口編程,一個接口多種實現(xiàn);利用state模式減少分支*三三、Making Method Calls Simpler(簡化函數(shù)調(diào)用
41、)(簡化函數(shù)調(diào)用) 7.Separate Query from Modifier(將查詢函數(shù)和修改函數(shù)分(將查詢函數(shù)和修改函數(shù)分離)離) 單一職責(zé)原則,建立兩個不同的函數(shù),其中一個負(fù)責(zé)查建立兩個不同的函數(shù),其中一個負(fù)責(zé)查詢,另一個負(fù)責(zé)修改詢,另一個負(fù)責(zé)修改 8.Parameterize Method(令函數(shù)攜帶參數(shù))(令函數(shù)攜帶參數(shù)) 通用函數(shù),建立單一函數(shù),以參數(shù)表達(dá)那些不同的值建立單一函數(shù),以參數(shù)表達(dá)那些不同的值 9.Replace Parameter with Explicit Methods(以明確函數(shù)取(以明確函數(shù)取代參數(shù))代參數(shù)) 多個if對應(yīng)對個函數(shù); 針對該參數(shù)的每一個可能值,
42、建立針對該參數(shù)的每一個可能值,建立一個獨立函數(shù)一個獨立函數(shù) - Refactoring: Improving the Design of Existing Code重構(gòu)案例控制圈復(fù)雜度的N種重構(gòu)技術(shù)-Refactoring: Improving the Design of Existing Code概念概念計算方法計算方法檢查工具檢查工具二不二二不二重構(gòu)方法重構(gòu)方法案例分析案例分析代碼生成工具優(yōu)化重構(gòu)前重構(gòu)后1.生成參數(shù)信息生成參數(shù)信息2.生成文件內(nèi)容生成文件內(nèi)容3.寫到文件寫到文件4.打印日志打印日志混亂的代碼是混亂思維的產(chǎn)物上傳文件代碼示例1.不是不是excel,返回,返回2.超過大小限制
43、,返回超過大小限制,返回3.不滿足條件,返回不滿足條件,返回4.文件內(nèi)容校驗文件內(nèi)容校驗5.多處String類型非空判斷if (StringUtil.isEmpty(username) throw new ICRClientException(username can not be null);if (StringUtil.isEmpty(password) throw new ICRClientException(password can not be null);if (udto = null) throw new ICRClientException(ICRUploadDTO can n
44、ot be null);/將原來的地方替換為checkStringParamEmpty(username, username);checkStringParamEmpty(password, password);checkStringParamEmpty(udto.getUrlPath(), urlPath);./新增一個方法private void checkStringParamEmpty(String value, String name) throws ICRClientException if (StringUtil.isEmpty(value) throw new ICRClien
45、tException(name + can not be null); 多String值判斷if (!udto.getPriority().equals(0) & !udto.getPriority().equals(1) & !udto.getPriority().equals(2) & !udto.getPriority().equals(3)throw new ICRClientException(priority must be 0/1/2/3);/將原來代碼替換為checkValueWithinList(udto.getPriority();./新增一個方法:
46、private void checkValueWithinList(String priority) throws ICRClientException if (!Arrays.asList(0, 1, 2, 3).contains(priority) throw new ICRClientException(priority must be 0/1/2/3); 多個catch的內(nèi)容相同int code = 0;try code = httpClient.executeMethod(post); catch (HttpException e) throw new ICRClientExcept
47、ion(e.getMessage(), e); catch (IOException e) throw new ICRClientException(e.getMessage(), e);/將原來的地方替換為int code = executeHttpClient(httpClient, post);./新增一個方法private int executeHttpClient(HttpClient httpClient, PostMethod post) throws ICRClientException int code; try code = httpClient.executeMethod
48、(post); catch (Exception e) throw new ICRClientException(e.getMessage(), e); return code;if判斷結(jié)果復(fù)雜化 if (code = 200) try if (post.getResponseBodyAsString().equals(ok) return true; catch (IOException e) throw new ICRClientException(e.getMessage(), e); return false; else if (code = 500) throw new ICRCli
49、entException(post.getResponseBodyAsString(); else throw new ICRClientException(code + : + post.getStatusText();return returnFinialResult(post, code);./新增一個方法private boolean returnFinialResult(PostMethod post, int code) throws ICRClientException, IOException if (code = 500) throw new ICRClientExcepti
50、on(post.getResponseBodyAsString(); if (code != 200) throw new ICRClientException(code + : + post.getStatusText(); try return post.getResponseBodyAsString().equals(ok); catch (IOException e) throw new ICRClientException(e.getMessage(), e); 本地變量始終不為nullpublic boolean uploadToICR(String username, Strin
51、g password, ICRUploadDTO udto) throws ICRClientException HttpClient httpClient = null; PostMethod post = null; httpClient = new HttpClient(); /some code here finally if (post != null) post.releaseConnection(); if (httpClient != null) httpClient.getHttpConnectionManager().closeIdleConnections(0); pub
52、lic boolean uploadToICR(String username, String password, ICRUploadDTO udto) throws ICRClientException HttpClient httpClient = new HttpClient(); PostMethod post = null; /some code here finally if (post != null) post.releaseConnection(); 讀取IO流的方法,為什么要自己實現(xiàn)?private byte readData(InputStream ins) throws
53、 IOException byte buf = new byte2048; int count = 0; int len = 0; byte data = new byte2048; byte result = null; try while (len = ins.read(data, 0, 2048) != -1) int newcount = count + len; if (newcount buf.length) byte newbuf = new byteMath .max(buf.length 1, newcount); System.arraycopy(buf, 0, newbu
54、f, 0, count); buf = newbuf; System.arraycopy(data, 0, buf, count, len); count = newcount; result = new bytecount; System.arraycopy(buf, 0, result, 0, count); finally ins.close(); return result;/使用apache io API的實現(xiàn): byte bytes = IOUtils.toByteArray(inputStream); /使用guava API的實現(xiàn): byte bytes1 = ByteStreams.toByteArray(inputStream);持續(xù)重構(gòu)重構(gòu)要盡早且要經(jīng)常進(jìn)行太多導(dǎo)入表明一個類過多地依賴于其他的類。您會注意到,由于一個類與很多其他的類耦合得太緊密,修改這個類會導(dǎo)致必須對很多其他的類進(jìn)行修改,這時就說明
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國擠出機(jī)機(jī)筒螺桿數(shù)據(jù)監(jiān)測研究報告
- 2025年度泵車設(shè)備租賃與施工質(zhì)量驗收合同
- 2025至2030年象拔蚌項目投資價值分析報告
- 2025至2030年中國大理石石桌數(shù)據(jù)監(jiān)測研究報告
- 2025至2030年胸部前推機(jī)項目投資價值分析報告
- 2025至2030年磨電機(jī)項目投資價值分析報告
- pp-r閥芯行業(yè)深度研究報告
- 2025至2030年電動液壓拉頂多用機(jī)項目投資價值分析報告
- 2025至2030年平紡錦滌紡項目投資價值分析報告
- 2025至2030年不銹鋼矩管項目投資價值分析報告
- 垃圾清運管理制度12篇
- 人教版二年級下冊口算題天天練1000道可打印帶答案
- 【跨境電商零售進(jìn)口稅收征管對策及建議16000字(論文)】
- DZ∕T 0332-2020 碳酸鹽巖油氣藏縫洞體雕刻法資源儲量估算規(guī)范(正式版)
- 心血管介入護(hù)士進(jìn)修匯報
- 施工組織設(shè)計內(nèi)部審批表
- 《企業(yè)的可持續(xù)發(fā)展》課件
- 零至三歲兒童及老年人中醫(yī)保健指導(dǎo)專業(yè)知識講座培訓(xùn)課件
- DB12-T 1305-2024 公路瀝青路面泡沫瀝青冷再生技術(shù)規(guī)范
- 范文語文評課稿15篇
- 2024年山東省春季高考技能考試汽車專業(yè)試題庫-中(多選題匯總)
評論
0/150
提交評論