第七計:串聯函數調用
當一個類的大部分函數被較為頻繁地調用,並且包含連續性地調用,那么可以考慮為這個類中那些沒有返回值的函數增加返回值,即返回對象本身,這樣就可以串聯函數調用,使用起來較為方便,舉個例子:
// 表示用戶的類 public class User{ public void setName(String name); public void setAge(int age); public void setPhoneNumber(int phoneNumber); }
下面是不使用串聯函數調用的情況:
User user = new User(); user.setName("West_Link"); user.setAge(3); user.setPhoneNumber(122333);
下面是使用串聯函數調用的情況:
User user = new User().setName("West_Link").setAge(3).setPhoneNumber(123333);
只需要為那些函數增加一個User對象的返回值即可,如下:
public User setName(String name){ this.name = name; return this; }
第八計:臨時變量在用到時才聲明
很多人喜歡在函數的開頭把所有要用到的臨時變量都聲明了,我認為這種方式有以下幾個缺點:
1、不利於代碼的閱讀,需要經常在變量的使用處和變量的聲明處跳轉,不方便。
2、容易造成資源的浪費,因為有些對象的初始化是比較耗費資源的,而函數可能在用到該對象之前返回。
3、不利於函數的拆分。
所以,我們應該盡可能降低臨時變量的作用域,那樣它能“搗亂“的范圍就被縮至最小了。
第九計:保持類的公有函數粒度最小化
一個類的公有函數不應該過多,那樣會使類變得臃腫、不易使用,我認為最佳狀態是絕大部分公有函數不能被拆分,也就是說,不存在那些通過其他公有函數也能達到目的的函數,例如下面的類:
public class StringArray{ // 獲取數組的大小 public int getSize(); // 判斷數組是否為空 public boolean isEmpty(); // 將數據添加到數組的某個索引 public void add(String value,int index); // 將數據添加到數組的末尾 public void addToLast(String value); // 將數據添加到數組的起始位置 public void addToFirst(String value); }
StringArray其實只需要兩個公有函數即可,即getSize和add,因為isEmpty可以通過getSize來達到相同的目的:getSize() == 0。類似地,addToLast、addToFirst也可以通過add來實現。不過,如果類的公有函數比較少,而且類似isEmpty類似的需求經常被用到,那么保留這些公有函數還是值得的。
第十計:將可訪問性降至最低
面向對象中的封裝性使得我們可以隱藏類或者接口的實現細節,所以,為了讓程序更易維護、接口或者類的使用更加簡單,我們應該盡可能降低成員變量或者成員函數的可訪問性,輔助函數一定要聲明為私有的,確保只將接口函數聲明為公有的,如果該輔助函數可能會被子類用到,則可以聲明為保護的。輔助類也應聲明為私有的,對於成員變量則一定要聲明為私有的,只提供必要的set或者get函數。總之,當我們增加新的類、成員變量、成員函數時,一定要合理地設置可訪問性,暴露給外界的越少越好。
第十一計:合並條件減少嵌套
條件判定如果嵌套的太多會大大降低程序的可讀性,很容易滋生Bug,例如:
if(a){ if(b || c){ if(d){ ... } } }
可以合並成:
if(a && (b || c) && d){ ... }
第十二計:循環中早用continue減少條件嵌套
除了通過合並條件來減少嵌套層次外,在for或者while循環中,可以用continue來減少條件嵌套,例如:
for(int i=0; i<100;i++){ if(a){ if(b){ if(c){ ... } } } }
這段代碼的嵌套深度是4,使用continue可以大大減少嵌套層次:
for(int i=0; i<100;i++){ if(!a) continue; if(!b) continue; if(!c) continue; ... }