快速业务通道

诊断Java代码: Broken Dispatch错误模式 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-19

诊断Java代码: Broken Dispatch错误模式

时间:2011-02-12 IBM Eric E. Allen

整体和部分

还记得这条谚语吗,“整体大于部分之和”?如果把一个个独立的事件组合成一个相互作用的整体,产生的结果会比单个个体的作用之和要大得多。

程序也是一样的道理。随着一个个新方法被添加到程序中,整个程序可能的控制流程迅速增加。对于大型程序而言,很快局面就会无法控制了。就象是一个荒谬而又不可思议的戏法,有时您得到的最终结果并不是您所期望的方向 ― 这同您在重载方法或者覆盖方法时遇到的情况有些类似。

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; }   ... }

诊断Java代码: Broken Dispatch错误模式(2)

时间:2011-02-12 IBM Eric E. Allen

在那篇文章中,我们把链表实现作为这些不可变列表的容器。

假设我们在一个独立的包中实现链表,我们知道这个包中类 LinkedList 的所有实例都将是 String 列表。我们可以象下面这样编写构造函数来强制定义该不变量:

清单 2. 为链表定义强制参数

public class LinkedList {   private List value;   /**   * Constructs an empty LinkedList.   */   public LinkedList() { this.value = new Empty(); }   /**   * Constructs a LinkedList containing only the given element.   */   public LinkedList(String _first) { this.value = new Cons(_first); }   /**   * Constructs a LinkedList consisting of the given Object followed by   * all the elements in the given LinkedList.   */   public LinkedList(String _first, LinkedList _rest) {   this.value = new Cons(_first, _rest.value);   }   public Object getFirst() { retur

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号