诊断Java代码: 设计可扩展的应用程序,第2部分 - 编程入门网
设计模式的最初书籍( 《设计模式》,Gamma 等;请参阅 参考资料)提出的设计模式之一。这一模式背后的思想是为复合数据类型定义一个抽象的“访问者”类。这个访问者类包含明显不同的方法,分别用于每一个具体的子类型。对我们的 Tree 类这种情况来说,我们可以定义一个抽象的 TreeVisitor 类,如下:
清单 3. 定义一个抽象的“树访问者”类
Tree 的每一个子类型都必须包含一个 accept 方法,该方法带一个 TreeVisitor 参数并调用自身的 TreeVisitor 的 accept方法: 清单 4. accept 方法必须调用自身对应的 accept 方法
现在,当我们想把新的功能性添加到树中时,我们可以只是定义 TreeVisitor 的新的具体子类并适当地定义 for方法(即 forBranch 和 forLeaf 方法)。例如,我们可以添加一个生成树的深度拷贝功能,如下: 清单 5. 新的 TreeCopier 功能对树进行拷贝
诊断Java代码: 设计可扩展的应用程序,第2部分(3)时间:2011-02-11 IBM Eric E. Allen访问者带来的麻烦 但如果我们也想扩展类 Tree 的具体子类型集合,则采用这种办法就会碰上麻烦。 第一个问题是现有的 TreeVisitors 将不包含用于新数据类型的 for 方法。这个问题可以这样解决:用包含这些新方法的新 TreeVisitors 建立现有 TreeVisitors 的子类型,并实现一个包含这些新方法的新子接口。 在我们的深度拷贝示例(清单 5)中,如果单元素叶被添加到我们的树中,则我们可以按如下方式扩展 TreeCopier (注意,必须给 NonEmptyLeaf 的 accept方法添加一个强制转型): 清单 6. 为非空叶而做的扩展
但仅仅以这种方式扩展 TreeVisitors 是不够的。 如果访问者带来更多访问者会怎么样? 原始的 TreeVisitors 可能会构造 TreeVisitors 的新实例。 TreeVisitor 的子类的实例现在将构造它们的超类的实例。 这个问题是常见的。通常,当在访问者中包含额外参数是很自然的时候,这些额外参数被传递到访问者的构造器,然后构造器把这些参数放置到字段中。在一个递归下降数据结构中,如果必须使用递归调用中的这些参数的不同值,则将会构造一个使用了新参数的新访问者。 例如,假设我们想创建一个 TreeVisitor ,用于对 Tree 的元素进行美化打印。我们可以用 TreeVisitor 的一个字段来跟踪打印子树时的缩进程度,以 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |