代碼複用的規則(下)

  消除case / if語句

  要儘量避免在代碼中出現判斷語句,來測試一個對象是否某個特定類的實例。通常,如果你需要這麼做,那麼,重新設計可能會有所幫助。我在工作中遇到這樣的一個問題:我們在使用JAVA做XML解析時,對每個標籤映射了一個JAVA類,採用SAX(簡單的XML接口API:Simple API for XML)模型。結果,代碼中反覆出現了大量的判斷語句,來測試當前的標籤類型。爲此,我們重新設計了DTD(文檔類型定義:Document Type Definition),爲每個標籤增加了一個固定的屬性:classname,而且重新設計了每個標籤映射的JAVA類的接口,統一了每個對象的操作:
  addElement(Element aElement); //增加子元素
  addAttribute(String attName, String attValue); //增加屬性;

  則徹底消除了所有的測試當前的標籤類型的判斷語句。每個對象通過 Class.forName(aElement.attributes.getAttribute("classname")).newInstence(); 動態創建,

  減少參數個數

  有大量參數需要傳遞的方法,通常很難閱讀。我們可以將所有參數封裝到一個對象中來完成對象的傳遞,這也有利於錯誤跟蹤。

  許多程序員因爲,太多層的對象包裝對系統效率有影響。是的,但是,和它帶來的好處相比,我們寧願做包裝。畢竟,"封裝"也是OO的基本特性之一,而且,"每個對象完成儘量少(而且簡單)的功能",也是OO的一個基本原則。

  類層次的最高層應該是抽象類

  在許多情況下,提供一個抽象基類有利做特性化擴展。由於在抽象基類中,大部分的功能和行爲已經定義好,使我們更容易理解接口設計者的意圖是什麼。

  由於JAVA不允許"多繼承",從一個抽象基類繼承,就無法再從其它基類繼承了。所以,提供一個抽象接口(interface)是個好主意,一個類可以實現多個接口,從而模擬實現了"多繼承",爲類的設計提供了更大的靈活性。

  儘量減少對變量的直接訪問

  對數據的封裝原則應該規範化,不要把一個類的屬性暴露給其它類,而是應該通過訪問方法去保護他們,這有利於避免產生波紋效應。如果某個屬性的名字改變,你只需要修改它的訪問方法,而不是修改所有相關的代碼。

  子類應該特性化,完成特殊功能

  如果一個子類只是使一個組件變成組件管理器,而不是實現接口功能,或者,重載某個功能,那麼,就應該使用一個外部的容器類,而不是創建一個子類。

  建議:類層次結構圖,不要太深;

  例如:下面的接口定義了組件的功能:發送消息;類Transceiver實現了該接口;而其子類Pool只是管理多個Transceiver對象,而沒有提供自己的接口實現。建議使用組合方式,而不是繼承!

public interface ITransceiver{
  public abstract send(String msg);
}

public class Transceiver implements ITransceiver {
  public send(String msg){
    System.out.println(msg);
  }
}

//使用繼承方式的實現
public class Pool extends Transceiver{
  private List  pool = new Vector();
  public void add(Transceiver aTransceiver){
    pool.add(aTransceiver);
}
public Transceiver get(int index){
    pool.get(index);
}
}

//使用組合方式的實現
public class Pool {
  private List  pool = new Vector();
  public void add(Transceiver aTransceiver){
    pool.add(aTransceiver);
}
public Transceiver get(int index){
    pool.get(index);
}
}
  拆分過大的類

  如果一個類有太多的方法(超過50個),那麼它可能要做的工作太多,我們應該試着將它的功能拆分到不同的類中,類似於規則四。

  作用截然不同的對象應該拆分

  在構建的過程中,你有時會遇到這樣的問題:對同樣的數據,有不同的視圖。某些屬性描述的是數據結構怎樣生成,而某些屬性描述的是數據結構本身。最好將這兩個視圖拆分到不同的類中,從類名上就可以區分出不同視圖的作用。

  類的域、方法也應該有同樣的考慮!

  儘量減少對參數的隱含傳遞

  兩個方法處理類內部同一個數據(域),並不意味着它們就是對該數據(域)做處理。許多時候,該數據(域)應該作爲方法的參輸入數,而不是直接存取,在工具類的設計中尤其應該注意。例如:

public class Test{
  private List  pool = new Vector();
  public void testAdd(String str){
    pool.add(str);
}
public Object testGet(int index){
    pool.get(index);
}
}
  兩個方法都對List對象pool做了操作,但是,實際上,我們可能只是想對List接口的不同實現Vector、ArrayList等做存取測試。所以,代碼應該這樣寫:
public class Test{
  private List  pool = new Vector();
  public void testAdd(List  pool, String str){
    pool.add(str);
}
public Object testGet(List  pool, int index){
    pool.get(index);
 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章