另一个有效的打开/关闭原则

我想你们中的许多读者都熟悉Open / Closed原理 。 它指出:

软件实体(类,模块,功能等)应打开以进行扩展,但应关闭以进行修改
—伯特兰·梅耶(Meyer)
面向对象的软件构造(1988)

此其他“打开/关闭”原理是完全无关的,但同样重要。 它指出:

当用某人的代码打开“某物”时,也必须将其关闭!
- 我
我的浴室(2014)

很简单? 那为什么我为什么经常偶然发现数据库连接未关闭( 释放到池中),套接字,输入流未关闭,输出流未关闭等? (但是,老实说,有时我忘记了后来者,我也感到内))。 如果在使用完资源后才释放资源,则可能会导致内存泄漏。 其他可能的后果与资源的性质有关:例如,当不释放数据库连接时,迟早池将耗尽,因此无法获取与数据库的新连接-基本上,您的应用程序将无法使用,需要重新启动应用程序服务器。

尽管如此,没有什么可以阻止我们关闭资源,只有一些事情要解决:

  1. 如上所示,关闭资源不是一种选择,必须确保。 Java使通过finally块成为可能(因此也需要相关的try块)。
  2. 大多数close() (或release()destroy()或您拥有的东西)方法签名都会引发已检查的异常。 如果您真的想要我的意见,这是一个设计错误,但是我们开发人员必须加以解决(老实说,这不是有人第一次决定必须由我来处理后果,这就是Management 1.0) )。

这是一个非常简单的示例:

Filefile=newFile("/path/to/file");
FileInputStreamfis=newFileInputStream(file);

try{
    // Do something with file
}finally{
    fis.close();
}

注释行6使用的方法的签名会引发检查异常,因此必须进行相应处理。 与大多数情况一样,在关闭时几乎无法恢复(根本无法读取)时抛出异常,不进一步抛出异常不仅仅是一个有效的选择。 无需使代码更加混乱,只需使用Apache Commons IOIOUtils.closeQuietly() (或其数据库对应的Apache Commons DBDBUtils.closeQuitely() )。

上面的finally块可以替换为:

finally{
    LOGGER.log("Couldn't close input stream on file "+file.getAbsolutePath());
    IOUtils.closeQuietly(fis);
}

(是的,在所有情况下,记录无法释放资源都是一个好习惯)

最后(可能不是双关语),人们可能还记得Java 7带来了AutoCloseable接口以及try-with-resources语法。 如果方法签名不引发异常,则使close()处理变得更加简单:

try(StringReaderreader=newStringReader(string)){
    // Do something with reader
}
即使不执行任何操作,StringWriter.close()签名也会引发异常

总之,请记住,持续集成平台是您的朋友,而Sonar(或Checkstyle,PMD和FinddBugs)等工具是检查未发布资源的好方法。

翻译自: https://blog.frankel.ch/another-valid-openclosed-principle/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值