诊断Java代码::Split Cleaner错误模式 - 编程入门网
结束前,只会有这样一种扩展)。
诊断Java代码::Split Cleaner错误模式(2)时间:2011-02-10 IBM Eric E. Allen症状 现在,请注意数据库连接被传递到了 TableWalker 的构造函数中。一旦完成对表的遍历,它就将关闭连接。 所以,在这个例子中,我们采用第二种策略来清除连接。我们已经尝试过沿着每一条执行路径分别关闭连接。 让我们假设在我们的系统环境中,在一次遍历数据后关闭连接是有意义的(例如,也许这段代码会被从命令提示符中调用)。即使在那种情况下,我们也不能捕捉到每一条可能的执行路径 — 如果抛出了 SQLException ,程序可能会在关闭连接前异常终止。 因为 SQLException 在成熟代码中很少见,所以这个错误可能在很长一段时间内都不会(可能在原开发人员已经转行后也不会)表现出什么症状。自然地,这使得在症状 真的表现出来时,诊断起来就更加困难。 但是如果扩展了代码,就会有一些方式使症状的出现变得快得多。 例如,我们假设在原始代码写好后,发现存档的许多电话号码明显是过时的。于是管理人员决定把所有员工的电话号码都替换为 411。为完成这个更新,新写一个 TableWalker 如下: 清单 2. 更新过时数据的 walker 代码
因为 TableFixer 也继承 TableWalker ,所以在这个类的一个实例上调用 walk 将关闭与该数据库的连接,就象 TablePrinter 一样。如果一个程序试图用同一个连接生成两个 walker 的实例,将发现第一个 walker 一完成遍历后连接就被关闭了。 编程新手很容易犯这样的错误,特别是如果不变量 ― 就是说只能构造一个 walker ― 没有文档或未测试过的话。 治疗及预防措施 当您发现有一条执行路径中没有包含适当的清除代码时,您可能会上当,只是简单地把它添加到那条路径中。 例如,您可以把 walk 方法的程序正文包到一个 try 程序块中,并加入一条 finally 子句以 确保关闭了连接。但这样一个解决方案却不是个好办法。 我们的 TableWalker 完全不必担心关闭连接的问题。即使每个 TableWalker 都 确实设法关闭了连接,我们也会陷入到第二种方式中,这种方式可以让这类错误模式自动现身 ― 当我们运行多个 walker 时,就会有 太多walker 试图关闭连接。 更糟的是,如果我们两次调用 con.close() (一次在 try 块中,一次在 catch 块中,而不是在 finally 语句中简单地单独调用),我们就会把 rogue tile 引入到代码中。 如果代码中添加了很多这种 rogue tile,那么要成功地重新组织代码将变得很困难。即使在测试期间,其中一些 rogue tile 可能处理的是基本上不会出现的执行路径。 一个好得多的解决方案是重新组织代码,用第一种方式来管理这些资源:把获得和释放资源的代码放到同一个方法中。 Andrew Hunt 和 Dave Thomas 在他们的一本优秀书籍 The Pragmatic Programmer 中用一个成语 ― “有始有终”来提倡这种思想。每个方法都要负责把它获得的资源释放掉。在我们的示例中,就是把对 con.close() 的调用移到类 Example 的 main 方法 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |