诊断Java代码: 深度优先访问器和中断的分派 - 编程入门网
y(Branch that,
Boolean left_result,
Boolean right_result)
{
return defaultCase(that);
}
...
}
现在,当在这样一个复合上实现深度优先访问器时,我们只需要为那些缺省情况下不处理的情况指定代码。 当复合层次结构的深度大于一层时,我们还可能需要为该层次结构的每个子树提供单独的缺省方法。可以将这些缺省方法定义成简单地调用父类的缺省方法。但在必要时,可以覆盖它们。 一旦完成了这些操作,我们就获得了使功能包括在复合类中的简洁性,同时保留了普通访问器的所有优点。 当然,也有警告 对于大多数向下深度优先的访问器,我们仍可以使用深度优先访问器。只要覆盖那些我们不想遍历深度优先的 for*() 方法(与 for*Only() 方法相对)。 然而,这种方法也有一个警告:很容易遇到 中断的分派。还记得它们吗?当我们意外重载一个方法而不是覆盖父类中的它的实现时,会发生 Broken Dispatch 错误模式。通过深度优先访问器,特别容易发生这种情况。 假设我们想要覆盖父类的一个 for*() (而不是 for*Only() )方法之一。这个 for*() 方法说明将采用它所操作的节点,但和 for*Only() 方法不同,它不接受访问子节点的结果。现在,因为我们正在编写 for*() 和 for*Only() 方法,所以不难想象我们会遗漏且意外地将 for*Only() 写成一个 for*() 方法的名称。 如果我们这样做了,代码将正常编译,但我们将无法覆盖 for*() 方法。相反,我们可用不同说明的新方法使 for*Only() 方法重载。 另外,永远不要调用这个新的 for*Only() 方法。类似这样的中断分派可能是隐藏特别深的错误,需要深入跟踪 — 类型检查器捕捉不到它们并且您决不知道它们何时或者是否真正发出了一个错误信号。在最坏的情况下,中断的分派将只以这样一种方式(其结果看似十分合理,但实际上是绝对错误的)修改程序的行为。 关于防止这些问题,我只能说它们是最好的示例,说明了为什么在编写代码之前(或同时)编写单元测试会节省时间,以及为什么应该经常运行那些测试! 因此,您就知道了为什么深度优先访问器很酷以及它们会怎样刺痛您。我要感谢我们研究实验室的研究生 Brian Stoler,他首先向我介绍了这种模式。深度优先访问器是通过“Java 树构建器(Java Tree Builder)”构造的,它是一种可以从 参考资料中免费获得的工具,用于根据 JavaCC 语法自动生成一个复合的层次结构(加上访问器)。 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |