好圈復雜度概念重構方法及案例分析潘洪亮2015-12-03_第1頁
好圈復雜度概念重構方法及案例分析潘洪亮2015-12-03_第2頁
好圈復雜度概念重構方法及案例分析潘洪亮2015-12-03_第3頁
好圈復雜度概念重構方法及案例分析潘洪亮2015-12-03_第4頁
好圈復雜度概念重構方法及案例分析潘洪亮2015-12-03_第5頁
已閱讀5頁,還剩58頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、揚帆起航圈復雜度圈復雜度Cyclomatic Complexity is 17 (max allowed is 7).Cyclomatic Complexity is X (max allowed is X) 我的QQ:28797575知道做什么嗎?文檔示例 無目錄 有目錄不聚焦不知道目標,不知道總體結構不知道是否合理沒有層次是否有遺漏帶來時間成本質量問題4知道做什么嗎? QQ: 28797575圈復雜度 概念概念概念計算方法計算方法檢查工具檢查工具二二不不二二重構方法重構方法案例分析案例分析McCabe復雜度圈復雜度圈復雜度基本復雜度基本復雜度模塊設計復雜度模塊設計復雜度設計復雜度設計復雜度

2、集成復雜度集成復雜度行數行數全局數據復雜度全局數據復雜度局部數據復雜度局部數據復雜度病態數據復雜度病態數據復雜度規范化復雜度規范化復雜度框架群:181124238 我的QQ:307087558(1)圈復雜度(Cyclomatic Complexity (v(G) )l概念圈復雜度是用來衡量一個模塊判定結構的復雜程度,數量上表現為獨立路徑的條數。l計算方法如果一個模塊流程圖有e條邊n個節點, 它的圈復雜度v(G)=e-n+2。 QQ: 28797575 圈復雜度(Cyclomatic Complexity)是一種代碼復雜度的衡量標準。它可以用來衡量一個模塊判定結構的復雜程度,數量上表現為獨立線性

3、路徑條數,也可理解為覆蓋所有的可能情況最少使用的測試用例數。圈復雜度大說明程序代碼的判斷邏輯復雜,可能質量低且難于測試和維護。程序的可能錯誤和高的圈復雜度有著很大關系。 圈復雜度主要與分支語句(if、else、switch 、for等)的個數成正相關。當一段代碼中含有較多的分支語句,其邏輯復雜程度就會增加。什么是圈復雜度 QQ: 28797575示例下面這個實例中,單元測試的覆蓋率可以達到100%,但是很容易發現這其中已經漏掉了一個NPE的測試用例。case1方法的圈復雜度為2,因此至少需要2個用例才能完全覆蓋到其所有的可能情況。/程序原代碼,圈復雜度為 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); 圈復雜度主要與分支語句(if、else、,switch 等)的個數成正相關。當一段代碼中含有較多的分支語句,其邏輯復雜程度就會增加。 QQ: QQ: 28797575圈復雜度 計算概念概念計算方法計算方法檢查工具檢查工具二不二二不二重構方法重構方法案例分析案例分析 QQ: 28797575示例 如

5、果一個模塊流程如下有e條邊n個節點,它的圈復雜度v(G) = e-n+2 例: QQ: 28797575圈復雜度的計算 圈復雜度(cyclomatic complexity): M = E N + 2P E: 邊的數量 N: 節點的數量 P: 分離部分的數量,一般為1,都是聯通的 圈數(cyclomatic number): M = E N + P E,N,P參數同上 圈復雜度和圈數之間的關系為: 對有向圖A,將A的每個出口(exit)與相應的入口(entrance)相連得到有向圖B,則A的圈復雜度與B的圈數相等 圈復雜度又叫做CC復雜度,也可能被稱為循環復雜度,它表達的是if . then

6、. else ., swith . case ., 循環語句等分支語句造成的程序控制流復雜程度 QQ: 28797575計算公式補充 通常使用的計算公式是V(G) = e n + 2 , e 代表在控制流圖中的邊的數量(對應代碼中順序結構的部分),n 代表在控制流圖中的節點數量,包括起點和終點(1、所有終點只計算一次,即便有多個return或者throw;2、節點對應代碼中的分支語句)。 QQ: 28797575 例如下圖示例一個單入口、單出口的程序圖(不是結構化程序圖),其圈復雜度為10-7+2=5: 從節點G到A添加一條有向邊,則成為一個強連通有向圖(該方法對其它結構化程序圖同樣適用),其

7、圈數為11-7+1=5,與上圖的圈復雜度相同: 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 根據公式 V(G) = e n + 2 = 12 8 + 2 = 6 。case2的圈復雜段為6。說明一下為什么n = 8,雖然圖上的真正節點有12個,但是其中有5個節點為throw、return,這樣的節點為end節點,只能記做一個。計算示例檢查工具概念概念計算計算檢查工具檢查工具二二不不二二重構重構 QQ: 28797575檢查工具 開發中常用的檢測圈復雜度的工具,PMD,checkstyle都可以檢測到高復雜度的代碼塊 Eclipse Metric 插件:有效地查出復雜度 JavaNCSS NCSS表示No

9、n Commenting Source S QQ: 28797575工具工具目的目的Eclipse 插件的插件的 URLCheckStyle編碼標準分析http:/eclipse- QQ: 28797575直接管好幾百人女:有三室兩廳嗎?男:沒有 女:有路虎,奧迪嗎? 男:沒有! 女:有7位數存款嗎(? 男:沒有+! 女:那你有啥? 男:我 女轉身就走,。 突然男的說:我管理幾百人(。 女立刻回頭抱住男的腰,滿臉崇拜的說道:死鬼,你不早說,這就夠了!那是什么公司高層? 男:我是群主群主燒鍋爐翻樣中國版主 QQ: 2879757572原則如果你二,你就關注7+2件及以上事情【二貨九個圈】如果你不

10、二,你就關注7-2件及以下事情【不二五個圈】圈復雜度高的,可以重構為如:1.參數判斷2.取數據3.數據預處理4.數據轉換5.返回數據每一步可以是一個獨立的方法這樣主干邏輯非常的清晰,也就不二金字塔金字塔原理:有目標、有層次、有順序原理:有目標、有層次、有順序總分總結構總分總結構把大象放冰箱里,統共分幾步?把大象放冰箱里,統共分幾步? QQ: 28797575代碼大全25知道做什么嗎?26總總共共分分5步步評審、會議常見問題27如果去掉第二層如果去掉第二層圈復雜度是。圈復雜度是。 QQ: 28797575寫文檔沒有目錄大綱模塊設計:一個包下N多個類代碼:超大方法超大類圈復雜度的重構控制圈復雜度的

11、N種重構技術-Refactoring: Improving the Design of Existing Code概念概念計算方法計算方法檢查工具檢查工具二不二二不二重構方法重構方法案例分析案例分析金字塔原理金字塔原理總分總結構總分總結構把大象放冰箱里,統共分幾步?把大象放冰箱里,統共分幾步?金字塔原理金字塔原理 寫代碼和寫文章、畫畫寫代碼和寫文章、畫畫總分總結構總分總結構把大象放冰箱里,統共分幾步?把大象放冰箱里,統共分幾步?業務重構業務重構架構重構架構重構設計重構設計重構代碼重構代碼重構重復重復。代碼重復、結構重復、邏輯重復。重復的代碼是抽象不夠的表現。如果是一個獨立完整的概念,可以提取成

12、一個子程序(抽象)。舉例:多處的排序算法。冗長子程序冗長子程序。如果把子程序的一部分提取來作為另一個獨立的子程序,可以讓代碼更清晰,就提取成子程序。循環過長或嵌套過深循環過長或嵌套過深。循環內部的復雜代碼往往可以轉換成子程序。嵌套過深可以用前面“語句”中提過的方法解決。子程序命名不當子程序命名不當。需要子程序重命名,或合并、拆分子程序。難懂、拙劣的代碼難懂、拙劣的代碼。需要重整邏輯和流程。代碼重構代碼重構降低圈復雜度的方法重構l 概念 重構(Refactoring)就是在不改變軟件現有功能的基礎上,通過調整程序代碼改善軟件的質量、性能,使其程序的設計模式和架構更趨合理,提高軟件的擴展性和維護性

13、。l 重構方法 重復代碼或者相似代碼提取為一個新的方法 將過長的方法按功能拆分成小的方法 將過大類的功能拆分成多個功能單一的小類l 推薦書籍 重構改善既有代碼的設計 作者:Martin Fowler 書中列出了長達70條的重構名錄,提供了具體重構的方法和重構的技巧。將幫助開發人員一次一小步地修改代碼,減少了開發過程中的風險。 QQ: 28797575Page 32可以直接降低圈復雜度的10種重構技術針對結構化編程:Composing Methods(重新組織你的函數)1.Extract Method(提煉函數)2.Substitute Algorithm(替換你的算法)Simplifying

14、Conditional Expressions(簡化條件表達式)3.Decompose Conditional(分解條件式)4.Consolidate Conditional Expression(合并條件式)5.Consolidate Duplicate Conditional Fragments(合并重復的條件片斷)6.Remove Control Flag(移除控制標記)Making Method Calls Simpler(簡化函數調用)7.Separate Query from Modifier(將查詢函數和修改函數分離)8.Parameterize Method(令函數攜帶參數)9

15、.Replace Parameter with Explicit Methods(以明確函數取代參數)- Refactoring: Improving the Design of Existing Code針對面向對象編程:10.Replace Conditional with Polymorphism(以多態取代條件式)控制圈復雜度的10種重構技術總結可以直接降低圈復雜度的9種重構技術(針對結構化編程):*一、Composing Methods(重新組織你的函數) 1.Extract Method(提煉函數) 分為不同的step步驟進行處理,主干邏輯方法控制在7個以內 將代碼放進一個獨立函數

16、中,并讓函數名稱解釋該函數的用途 2.Substitute Algorithm(替換你的算法) 將函數本體替換為另一個更清晰、簡化的算法 ,如多值匹配 candidates.contains*二、Simplifying Conditional Expressions(簡化條件表達式) 3.Decompose Conditional(分解條件式) 從if、then、else三個段落中分別提煉出獨立函數 4.Consolidate Conditional Expression(合并條件式) 將多個條件合并 為 c1|c2&c3,并提煉為一個函數 5.Consolidate Duplicate Co

17、nditional Fragments(合并重復的條件片斷) 多個條件都執行的代碼,將重復代碼搬移到條件式之外 6.Remove Control Flag(移除控制標記) 以break和return取代控制標記* 10.Replace Conditional with Polymorphism(以多態取(以多態取代條件式)代條件式) 將整個條件式的每個分支放進一個子類的重載方法將整個條件式的每個分支放進一個子類的重載方法中,然后將原始函數聲明為抽象方法中,然后將原始函數聲明為抽象方法 面向接口編程,一個接口多種實現;利用state模式減少分支*三三、Making Method Calls Si

18、mpler(簡化函數調用)(簡化函數調用) 7.Separate Query from Modifier(將查詢函數和修改函數分(將查詢函數和修改函數分離)離) 單一職責原則,建立兩個不同的函數,其中一個負責查建立兩個不同的函數,其中一個負責查詢,另一個負責修改詢,另一個負責修改 8.Parameterize Method(令函數攜帶參數)(令函數攜帶參數) 通用函數,建立單一函數,以參數表達那些不同的值建立單一函數,以參數表達那些不同的值 9.Replace Parameter with Explicit Methods(以明確函數取(以明確函數取代參數)代參數) 多個if對應對個函數; 針

19、對該參數的每一個可能值,建立針對該參數的每一個可能值,建立一個獨立函數一個獨立函數 - Refactoring: Improving the Design of Existing CodePage 34Extract Method(提煉函數)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) prin

21、tBanner(); 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.elements()

22、; 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);將這段代碼放進一個獨立函數中,將這段代碼放進一個獨立函數中,并讓函數名稱解釋該函數的用途并讓函數名稱解釋該函數的用途你有一段代碼可以被組織在一起并獨

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.asList(ne

24、w StringDon, John,Kent); for (int i=0; ipeople.length; i+) if (candidates.contains(peoplei) return peoplei; return ;你想要把某個算法替換為另一個更清晰的算法將函數本體替換為另一個算法多值判斷用集合多個key,用map【當這個值,調用某個服務】多值判斷用集合Page 36Decompose Conditional(分解條件式)if (date.before (SUMMER_START) | date.after(SUMMER_END) charge = quantity * _wi

25、nterRate + _winterServiceCharge;else charge = quantity * _summerRate;if (notSummer(date) charge = winterCharge(quantity);else charge = summerCharge (quantity);你有一個復雜的條件語句從從if、then、else三個段落中分別提煉出獨立函數三個段落中分別提煉出獨立函數專注、聚焦專注、聚焦Page 37Consolidate Conditional Expression(合并條件式)double disabilityAmount() if (

26、_seniority 12) return 0; if (_isPartTime) return 0; / compute the disability amountdouble disabilityAmount() if (isNotEligableForDisability() return 0; / compute the disability amount將這些判斷合并為一個條件式,并將這個條件式提煉成為一個獨立函數將這些判斷合并為一個條件式,并將這個條件式提煉成為一個獨立函數你有一系列條件判斷,都得到相同結果Page 38Consolidate Duplicate Condition

27、al Fragments(合并重復的條件片斷)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();在條件式的每個分支上有著相同的一段代碼。將這段重復代碼搬移到條件式之外將這段重復代碼搬移到條件式之外反反CVS模式模式Page 39Remove Control Flag(移除控制標記)void checkSecurity(String

28、 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; ; i

29、f (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(int

30、start, int end) if (lastUsage() start) return Math.min(lastUsage(),end) -start; else return 0;若干函數做了類似的工作,但在函數本體中卻包含了不同的值建立單一函數,以參數表達那些不同的值建立單一函數,以參數表達那些不同的值重構為多參函數重構為多參函數Page 42Replace Parameter with Explicit Methods(以明確函數取代參數)void setValue (String name, int value) if (name.equals(height) _height =

31、 value; if (name.equals(width) _width = value; Assert.shouldNeverReachHere();void setHeight(int arg) _height = arg;void setWidth (int arg) _width = arg;函數實現完全取決于參數值而采取不同反應針對該參數的每一個可能值,建立一個獨立函數針對該參數的每一個可能值,建立一個獨立函數Page 43Replace Conditional with Polymorphism(以多態取代條件式)double getSpeed() switch (_type)

32、case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() *_numberOfCoconuts; case NORWEGIAN_BLUE: return (_isNailed) ? 0 : getBaseSpeed(_voltage); throw new RuntimeException (Should be unreachable);你手上有個條件式,它根據對象類型的不同而選擇不同的行為將整個條件式的每個分支放進一個子類的重載方法中,然后將原始函數聲明為抽象方法將整

33、個條件式的每個分支放進一個子類的重載方法中,然后將原始函數聲明為抽象方法+getSpeed()BirdBird+getSpeed()EuropeanEuropean+getSpeed()AfricanAfrican+getSpeed()Norwegian BlueNorwegian Blue面向接口編程面向接口編程利用state模式減少分支 劉翔有三種狀態三種狀態,生病狀態,正常狀態,興奮狀態public void run() if(state = NORMAL_STATE) /正常狀態下跑 System.out.println(100米,跑完共用時15秒!); else if(state =

34、 MALUM_STATE) /生病狀態下跑 System.out.println(100米,跑完共用時20秒!); else if(state = EXCITED_STATE) /興奮狀態下跑 System.out.println(100米,跑完共用時10秒!); else System.out.println(未知的狀態);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秒!); 采用狀態模式的運動員public class Gamer /當前狀態 private IState state = new NormalState(); /改變狀態的方法 public v

36、oid setState(IState state) this.state = state; /狀態行為方法,同上面的Gamer 類相比這里沒有if.else if判斷 public void run() state.doRun(); 利用state模式減少分支 public static void main(String args) /沒有使用狀態設計模式 com.bill99.pattern.Gamer game = new com.bill99.pattern.Gamer(); game.setState(0); game.run(); game.setState(1); game.ru

37、n(); game.setState(2); game.run(); System.out.println(-); /使用狀態設計模式 /正常狀態下跑 Gamer gamer = new Gamer(); gamer.run(); /生病狀態下跑 gamer.setState(new MalumState(); gamer.run(); /興奮狀態下跑 gamer.setState(new ExcitedState(); gamer.run(); SuperExcitedState假如我們再擴展一個超級興奮的狀態SuperExcitedState,只需實現IState接口,定義好該狀態的行為,

38、調用如下gamer.setState(new SuperExcitedState();gamer.run();如果以后維護的話,要再加一個超級興奮的狀態,得要改原來的源代碼,添加一個代表超級興奮的成員變量,再改if.else if判斷,這樣做不符合OO設計原則,實現不了程序的松耦合。控制圈復雜度的10種重構技術總結可以直接降低圈復雜度的9種重構技術(針對結構化編程):*一、Composing Methods(重新組織你的函數) 1.Extract Method(提煉函數) 分為不同的step步驟進行處理,主干邏輯方法控制在7個以內 將代碼放進一個獨立函數中,并讓函數名稱解釋該函數的用途 2.S

39、ubstitute Algorithm(替換你的算法) 將函數本體替換為另一個更清晰、簡化的算法 ,如多值匹配 candidates.contains*二、Simplifying Conditional Expressions(簡化條件表達式) 3.Decompose Conditional(分解條件式) 從if、then、else三個段落中分別提煉出獨立函數 4.Consolidate Conditional Expression(合并條件式) 將多個條件合并 為 c1|c2&c3,并提煉為一個函數 5.Consolidate Duplicate Conditional Fragments(

40、合并重復的條件片斷) 多個條件都執行的代碼,將重復代碼搬移到條件式之外 6.Remove Control Flag(移除控制標記) 以break和return取代控制標記* 10.Replace Conditional with Polymorphism(以多態取(以多態取代條件式)代條件式) 將整個條件式的每個分支放進一個子類的重載方法將整個條件式的每個分支放進一個子類的重載方法中,然后將原始函數聲明為抽象方法中,然后將原始函數聲明為抽象方法 面向接口編程,一個接口多種實現;利用state模式減少分支*三三、Making Method Calls Simpler(簡化函數調用)(簡化函數調用

41、) 7.Separate Query from Modifier(將查詢函數和修改函數分(將查詢函數和修改函數分離)離) 單一職責原則,建立兩個不同的函數,其中一個負責查建立兩個不同的函數,其中一個負責查詢,另一個負責修改詢,另一個負責修改 8.Parameterize Method(令函數攜帶參數)(令函數攜帶參數) 通用函數,建立單一函數,以參數表達那些不同的值建立單一函數,以參數表達那些不同的值 9.Replace Parameter with Explicit Methods(以明確函數取(以明確函數取代參數)代參數) 多個if對應對個函數; 針對該參數的每一個可能值,建立針對該參數的

42、每一個可能值,建立一個獨立函數一個獨立函數 - Refactoring: Improving the Design of Existing Code重構案例控制圈復雜度的N種重構技術-Refactoring: Improving the Design of Existing Code概念概念計算方法計算方法檢查工具檢查工具二不二二不二重構方法重構方法案例分析案例分析代碼生成工具優化重構前重構后1.生成參數信息生成參數信息2.生成文件內容生成文件內容3.寫到文件寫到文件4.打印日志打印日志混亂的代碼是混亂思維的產物上傳文件代碼示例1.不是不是excel,返回,返回2.超過大小限制,返回超過大小限

43、制,返回3.不滿足條件,返回不滿足條件,返回4.文件內容校驗文件內容校驗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 not be nu

44、ll);/將原來的地方替換為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 ICRClientExcepti

45、on(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();./新增一個方法:private void checkVa

46、lueWithinList(String priority) throws ICRClientException if (!Arrays.asList(0, 1, 2, 3).contains(priority) throw new ICRClientException(priority must be 0/1/2/3); 多個catch的內容相同int code = 0;try code = httpClient.executeMethod(post); catch (HttpException e) throw new ICRClientException(e.getMessage(),

47、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(post); catch (Excep

48、tion e) throw new ICRClientException(e.getMessage(), e); return code;if判斷結果復雜化 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 ICRClientException(post.ge

49、tResponseBodyAsString(); 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 ICRClientException(post.getResponseB

50、odyAsString(); 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, String password, ICRUploa

51、dDTO 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); public boolean uploadTo

52、ICR(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流的方法,為什么要自己實現?private byte readData(InputStream ins) throws IOException byte bu

53、f = 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, newbuf, 0, count); buf =

54、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的實現: byte bytes = IOUtils.toByteArray(inputStream); /使用guava API的實現: byte bytes1 = ByteStreams.toByteArray(inputStream);持續重構重構要盡早且要經常進行太多導入表明一個類過多地依賴于其他的類。您會注意到,由于一個類與很多其他的類耦合得太緊密,修改這個類會導致必須對很多其他的類進行修改

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論