返回總目錄 十四、Temporary Field(令人迷惑的暫時欄位) 1、某個實例變數僅為某種特定的情況而設 2、某些實例欄位僅為某個函數的複雜演算法少傳參數而設 將這些變數和相關函數提煉到一個獨立的類中。 十五、Message Chains(過度耦合的消息鏈) 如果你看到用戶向一個對象請求另一個對 ...
十四、Temporary Field(令人迷惑的暫時欄位)
1、某個實例變數僅為某種特定的情況而設
2、某些實例欄位僅為某個函數的複雜演算法少傳參數而設
將這些變數和相關函數提煉到一個獨立的類中。
十五、Message Chains(過度耦合的消息鏈)
如果你看到用戶向一個對象請求另一個對象,然後再向後者請求另一個對象,然後在請求另一個對象……這就是消息鏈。
實際代碼就是一長串的getThis()或者一長串臨時變數。
使用隱藏“委托關係”(這個後面會講)來進行重構。當然了,可以在消息鏈的任何位置運用。
十六、Middle Man(中間人)
過度運用委托。
1、某個類介面有一半的函數都委托給其他類,這時應“移除中間人”:讓客戶直接調用委托類。
2、如果只有少數幾個函數,那就直接調用
3、如果中間人還有其他行為,以繼承取代委托,讓委托類繼承受托類。
十七、Inappropriate Intimacy(狎昵關係)
兩個類過於親密必須拆散。
1、可以提煉一個類,將兩者的共同點提煉到這個類中。
2、可以去掉類之間不必要的關聯。
3、將繼承改為委托,把子類從繼承體系移出
十八、Alternative Classes with Different Interfaces(異曲同工的類)
兩個函數做同一件事,但是簽名不同。將兩個函數合併,並根據用途重新命名。
十九、Incomplete Library Class(不完美的類庫)
類庫函數構造的不夠好,又不能修改它們
1、如果只想修改類的一兩個函數,可以引入外加函數。
2、如果想要添加一大堆額外行為,建立一個新類包含這些額外行為,讓其成為子類。
二十、Data Class(純稚的數據類)
所謂Data Class:類只有一些欄位,以及訪問這些欄位的函數。
1、如果擁有public欄位,則將其封裝起來
2、如果擁有集合類欄位,則將其封裝起來
3、對於不能修改的欄位,去除set方法
二十一、Refused Bequest(被拒絕的遺贈)
派生類僅使用了基類很少一部分成員函數
如果子類復用了父類的行為(實現),卻又不願意支持基類的介面,那就使用委托替代繼承。
二十二、Comments(過多的註釋)
常常有這種情況:一段代碼有著長長的註釋,而這些註釋之所以存在是因為代碼很shit。
這時候我們可以先找到各種“壞味道”,然後重構它。
當你感覺需要撰寫註釋時,請先嘗試重構,試著讓所有的註釋都變得多餘。
記得有一句話是這麼說的:註釋的最高境界——代碼即註釋。
當然了,這也不是說,我們不應該寫註釋。只是註釋要寫對地方。
小結
到這裡所有的“壞味道”已經講完了。平常我們在寫代碼的時候,一定要註意這些壞味道。
“如果尿布臭了,就換掉它”。這句話同樣適用於我們的代碼。
“代碼的壞味道”的系列文章主要是對常見的22種壞味道的瞭解和熟悉,以促使我們在開發過程中,能夠經常性地分析和思考程式,尋找已經散髮出壞味道的地方並對其進行適當重構,使得代碼更加“漂亮”。
在後續的文章中,我會介紹一系列的重構手法來消除這些壞味道。
To Be Continued...