診斷Java代碼: Broken Dispatch錯誤模式

來源:互聯網
上載者:User

整體和部分

還記得這條諺語嗎,“整體大於部分之和”?如果把一個個獨立的事件組合成一個相互作用的整體,產生的結果會比單個個體的作用之和要大得多。

程式也是一樣的道理。隨著一個個新方法被添加到程式中,整個程式可能的控制流程程迅速增加。對於大型程式而言,很快局面就會無法控制了。就象是一個荒謬而又不可思議的戲法,有時您得到的最終結果並不是您所期望的方向 ― 這同您在重載方法或者覆蓋方法時遇到的情況有些類似。

Broken Dispatch 錯誤模式

物件導向語言的最強大的特性之一就是繼承多態性。這一特性允許我們根據參數類型重載和覆蓋方法。但是,象其它功能強大的工具一樣,這個特性也會引入新的危險。

雖然 Java 程式員們很快就能學會管理一次調用中將調用哪個方法的規則,但在大型程式中卻很容易出現這種情況:在一個類中重載了一個方法,結果卻是以前在另一個類中可以啟動並執行代碼被中斷了。這樣的錯誤正符合我所說的 Broken Dispatch 模式。

該模式可以描述如下:

傳遞給某個重載方法,比如 foo 的參數,卻被傳給了另一個方法,比如 goo ,它支援更廣泛的參數類型。

goo 然後通過這些參數調用 foo 。

但是由於 goo 內的這些參數的靜態類型更為廣泛,因此,可能會調用方法 foo 的錯誤版本。

象這樣的錯誤很難診斷,因為可能只是添加了新的方法(而不是修改現有的方法)就引入了錯誤。而且,在發現問題之前,程式可能會繼續執行相當長的一段時間。

癥狀

為了說明這種模式的本質,讓我們來看看下面這段範例程式碼,它是為實現我前面的文章“ 空標誌錯誤模式”中的不可變列表而編寫的。

清單 1. 實現不可變列表

interface List {
  public Object getFirst();
  public List getRest();
}
class Empty implements List {
  public Object getFirst() { throw new NoSuchElementException(); }
  public List getRest() { throw new NoSuchElementException(); }
  public boolean equals(Object that) {
   return this.getClass() == that.getClass();
  }
}
class Cons implements List {
 
  Object first;
  List rest;
 
  Cons(Object _first) {
   this.first = _first;
   this.rest = new Empty();
  }
  Cons(Object _first, List _rest) {
   this.first = _first;
   this.rest = _rest;
  }
  public Object getFirst() { return this.first; }
  public List getRest() { return this.rest; }
  ...
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.