代碼里壞味道_第1頁
代碼里壞味道_第2頁
代碼里壞味道_第3頁
代碼里壞味道_第4頁
代碼里壞味道_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、重復(fù)代碼 癥狀: 重復(fù)的表達(dá)式 不同算法做相同的事 類似代碼 措施: 一個(gè)類中包含兩段重復(fù)代碼時(shí),使用提煉方法提煉方法置于一處 兩個(gè)相同層次的類含有重復(fù)代碼時(shí),提煉方法,方法上移提煉方法,方法上移 兩個(gè)無關(guān)類中出現(xiàn)重復(fù)代碼時(shí),提煉方法提煉方法至其中一個(gè)類或其他類中供調(diào)用例:方法上移例:方法上移class Customer private Date lastBillDate; addBill(Date dat,double amount)class RegularCustomer:Customer createBill(Date) chargeFor(Date start,Date end)cl

2、ass PreferredCustomer:Customer createBill(Date) chargeFor(Date start,Date end)class Customer private Date lastBillDate; addBill(Date dat,double amount) createBill(Date) abstract double chargeFor(Date start,Date end)class RegularCustomer:Customer chargeFor(Date start,Date end)class PreferredCustomer:

3、Customer chargeFor(Date start,Date end)3方法過長 癥狀: 存在大量的代碼行 注釋 條件和循環(huán) 措施: 每當(dāng)需要注釋時(shí),寫一個(gè)方法來代替注釋 絕大多數(shù)場合下,采取提煉方法技術(shù)提煉方法技術(shù)來縮短函數(shù) 方法帶有很多參數(shù)和臨時(shí)變量時(shí),采取查詢替換臨時(shí)變查詢替換臨時(shí)變量量和鏈?zhǔn)秸{(diào)用替換臨時(shí)變量鏈?zhǔn)秸{(diào)用替換臨時(shí)變量來消除臨時(shí)變量;采用引入引入?yún)?shù)對象參數(shù)對象和保留完整對象保留完整對象技術(shù)瘦身參數(shù)列表;重型武器:使用方法對象替換方法方法對象替換方法 使用分解條件語句分解條件語句處理?xiàng)l件表達(dá)式;使用集合閉包方法集合閉包方法替換循環(huán)例:查詢替換臨時(shí)變量例:查詢替換臨時(shí)變量

4、/這是未做重構(gòu)的簡單方法這是未做重構(gòu)的簡單方法double getPrice() int basePrice=_quantity*_itemPrice; double discountFactor; if(basePrice1000) discountFactor=0.95; else discountFactor=0.98; return basePrice*discountFactor;/重構(gòu)之后的主方法重構(gòu)之后的主方法double getPrice() return basePrice()*discountFactor();/把臨時(shí)變量賦值語句等號右邊的表達(dá)式提煉成一個(gè)方法private

5、 int basePrice() return _quantity*_itemPrice;/有了basePrice()的基礎(chǔ)很容易提煉出下面的方法private double discountFactor() if(basePrice()1000) return 0.95; else return 0.98;5例:引入?yún)?shù)對象例:引入?yún)?shù)對象class Entry. Entry(double value,Date chargeDate) _value=value; _chargeDate=chargeDate; Date getDate() return _chargeDate; double

6、 getValue() return _value; private Date _chargeDate; private double _value;class Account. double getFlowBetween(Date start,Date end) double result=0; Enumeration e = _entries.elements(); while(e.hasMoreElements() Entry each=(Entry)e.nextElement(); if(each.getDate().equals(start)|each.getDate().equal

7、s(end)|(each.getDate().after(start)&each.getDate().before(end) result+=each.getValue(); return result; double flow=anAccount.getFlowBetween(startDate,endDate);6例:引入?yún)?shù)對象例:引入?yún)?shù)對象class DateRange boolean include(Date arg) return (arg.equals(_start)|arg.equals(_end)&(arg.after(_start)|arg.before(

8、_end) DateRange(Date start,Date end) _start=start; _end=end; Date getStart() return _start; Date getEnd() return _end; private final Date _start; private final Date _end;class Account. double getFlowBetween(DateRange range) double result=0; Enumeration e = _entries.elements(); while(e.hasMoreElement

9、s() Entry each=(Entry)e.nextElement(); if(range.includes(each.getDate() result+=each.getValue(); return result; double flow=anAccount.getFlowBetween(new DateRange (startDate,endDate); 7例:保持對象完整int low = daysTempRange().getLow();int high = daysTempRange().getHigh();withinPlan = plan.withinRange(low,

10、high);withinPlan = plan.withinRange(daysTempRange();8類太大 癥狀: 出現(xiàn)太多實(shí)例變量 包含太多代碼 措施: 提煉類提煉類把一些變量打包 可以作為子類時(shí),提煉子類提煉子類 無法作為委托時(shí),提煉模塊提煉模塊參數(shù)列表太長 癥狀: 參數(shù)列表過長 參數(shù)列表變化頻繁 措施: 傳遞對象傳遞對象,使方法自己獲取它需要的參數(shù) 參數(shù)來自同一對象或是對象本身,保留整個(gè)對象為參數(shù)保留整個(gè)對象為參數(shù) 參數(shù)來自不同對象,引入?yún)?shù)對象引入?yún)?shù)對象或者引入命名參數(shù)引入命名參數(shù)發(fā)散式變化 癥狀: 一個(gè)類因?yàn)椴煌睦碛梢圆煌姆绞叫薷?措施: 將兩類變化涉及的方法拆為兩個(gè)對象

11、,每個(gè)對象只因?yàn)橥活愖兓兓?將某種特定原因造成的所有變化提煉為一個(gè)新類,新類處理這一類變化霰彈式修改 癥狀: 發(fā)生一次改變時(shí),需要修改多個(gè)類的多個(gè)地方 措施: 使用移動(dòng)字段和移動(dòng)方法將所有修改集中到單個(gè)類中。若現(xiàn)有類無好的候選者,創(chuàng)建;通常可以使用內(nèi)聯(lián)化類內(nèi)聯(lián)化類將整組行為整合到一起。特性依賴 癥狀: 一個(gè)方法調(diào)用其他類的方法比較多 一個(gè)方法調(diào)用到多個(gè)類的功能 措施: 移動(dòng)方法至另一適當(dāng)?shù)膶ο笾?看哪個(gè)類含有最多的數(shù)據(jù)就把方法和那些數(shù)據(jù)放在一起數(shù)據(jù)泥團(tuán) 癥狀: 兩個(gè)類中相同的實(shí)例變量 許多方法簽名中相同的參數(shù) 措施: 對于實(shí)例變量,使用提煉類將其變成一個(gè)對象 對于方法簽名,引入?yún)?shù)對象引

12、入?yún)?shù)對象或保留完整對象保留完整對象來瘦身基本類型偏執(zhí) 癥狀: 使用了基本類型(fixnum、string、array) 措施: 使用對象替換數(shù)據(jù)值使用對象替換數(shù)據(jù)值 使用多態(tài)替換類型碼使用多態(tài)替換類型碼 使用模塊擴(kuò)展替換類型碼使用模塊擴(kuò)展替換類型碼 使用狀態(tài)或策略模式替換類型碼使用狀態(tài)或策略模式替換類型碼 使用對象替換數(shù)組使用對象替換數(shù)組例:使用對象替換數(shù)組例:使用對象替換數(shù)組有一個(gè)數(shù)組String row=new String3;row0=Liverpool;row1=15;String name=row0;int wins=Integer.parseInt(row1);class Per

13、formance private string _name; private int _wins; public string getName() return _name; public void setName(string arg) _name=arg; public int getWins() return _wins public void setWins(int arg) _wins=arg; 16case語句 癥狀: 代碼使用了case語句 措施: 用多態(tài)替換case語句 提煉方法,先把case語句提煉出來; 移動(dòng)方法至需要多態(tài)行為的類; 選擇技術(shù):使用多態(tài)替換類型碼、模塊擴(kuò)展替

14、換類型碼、狀態(tài)或策略模式替換類型碼 若分支很少,只在一個(gè)方法里起作用,使用顯示方法替顯示方法替換參數(shù)換參數(shù)或引入引入Null對象對象來替換case語句平行繼承體系 癥狀: 為某個(gè)類增加子類時(shí),必須為另一個(gè)類增加子類 某個(gè)繼承體系類名前綴和另一個(gè)繼承體系類名前綴相同 措施: 使用移動(dòng)字段和移動(dòng)方法冗贅類 癥狀 類并沒有做什么工作 措施: 削減層次削減層次 內(nèi)聯(lián)化類或內(nèi)聯(lián)化模塊內(nèi)聯(lián)化類或內(nèi)聯(lián)化模塊純臆測的泛化 癥狀: 類或模塊沒太大用處 方法、代碼分支,或整個(gè)類的用戶只有測試用例 措施: 類或模塊沒太大用處,使用削減層次削減層次 不必要的委托,通過內(nèi)聯(lián)化類內(nèi)聯(lián)化類來移除 帶有未使用參數(shù)的方法,使用

15、移除參數(shù)移除參數(shù) 不必要的方法、代碼,刪除臨時(shí)字段癥狀: 某個(gè)實(shí)例變量僅為某種情況而設(shè)置 某些實(shí)例變量僅為某個(gè)函數(shù)的復(fù)雜算法少傳參數(shù)而設(shè)置措施: 提煉類提煉類,封裝這些變量和需要他們的方法為方法對象方法對象 引入引入null對象對象為變量無效時(shí)創(chuàng)建額外組件,消除條件代碼消息鏈 癥狀: 一長串的 get_This 或臨時(shí)變量 措施: 使用隱藏委托隱藏委托技術(shù)中間人 癥狀: 一個(gè)類的接口中有很多方法在委托另一個(gè)類 措施: 這種方法數(shù)目很多時(shí),使用移除中間人移除中間人技術(shù),直接和干活的對象打交道 這種方法的數(shù)目不多時(shí),內(nèi)聯(lián)化方法內(nèi)聯(lián)化方法到調(diào)用者中 這種方法包含額外的行為時(shí),使用層次替換委托層次替換

16、委托,將實(shí)際對象變成一個(gè)模塊 過分親密 癥狀 一個(gè)類訪問了另一個(gè)類的私有部分。 措施 使用移動(dòng)方法和移動(dòng)字段可以降低親密程度 將雙向關(guān)聯(lián)改成單向?qū)㈦p向關(guān)聯(lián)改成單向 使用提煉類將公共部分提煉到安全之處 子類知道太多父類不想讓他們知道的東西,使用委托替委托替換繼承換繼承讓他們離家異曲同工的類 癥狀: 完成相同工作,但卻使用了不同的方法名 措施: 使用重命名方法重命名方法 使用移動(dòng)方法將行為移到類中 因此出現(xiàn)冗余代碼時(shí),使用提煉模塊提煉模塊或引入繼承引入繼承來修正不完善的類庫 癥狀: 類庫中函數(shù)構(gòu)造的不夠好,想擴(kuò)展時(shí)可能很棘手 措施: 使用移動(dòng)方法將需要的行為直接移到類庫中去數(shù)據(jù)類 癥狀: 類僅由屬性構(gòu)成,純粹用來持有數(shù)據(jù),過分細(xì)致的依賴于其他類 措施: 對任何不應(yīng)被修改的實(shí)例變量采用移除設(shè)值方法移除設(shè)值方法 運(yùn)用封裝集合技術(shù)封裝集合技術(shù)封裝集合實(shí)例變量 嘗試移動(dòng)方法將相關(guān)行為移到數(shù)據(jù)類中,對一些設(shè)值方法和取值方法使用隱藏方法隱藏方法被拒絕的饋贈(zèng) 癥狀 子類不需要或僅需少部分父類的方法和數(shù)據(jù) 措施 創(chuàng)建兄弟子類,使用方法下移,將所有不用的方法移到兄弟類中(不推薦) 若子類沖用了行為卻不想支持父類里的公共方法時(shí),應(yīng)該使用委托替換繼承技術(shù)委托替換繼承技術(shù)注釋 癥狀: 存在注釋 措施: 提煉方法替代注釋 提煉之后還需注釋,則重命名方法 若需

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論