0

我有一个界面:

public interface FileRepository {
    String insert(File file) throws IOException;
    // other methods ...
}

我的实现insert(File file)使用本地(以避免并发问题)从其工厂方法java.security.MessageDigester中抛出检查异常。java.security.NoSuchAlgorithmException

public FileRepositoryImpl(String digestAlgo) throws NoSuchAlgorithmException {
    this.digestAlgo = digestAlgo;
    MessageDigest.getInstance(digestAlgo);
    }
@Override
public String insert(File file) throws IOException {
// initialize message digest
    MessageDigest messageDigest = null;
    try {
        messageDigest = MessageDigest.getInstance(digestAlgo);
    } catch (NoSuchAlgorithmException e) {
        LOGGER.fatal(MD_INIT_ERROR, e);
        return null;
}
    // other code ....
}
// other methods (may contain local MessageDigest)

我的实践:由于NoSuchAlgorithmException总是一个致命错误(这使得模块完全不可用),我尝试MessageDigest在我的构造函数中初始化 a 来测试 parameter digestAlgo,因此构造函数可以抛出异常,而不是 from insert(File)。另一个原因是接口不允许NoSuchAlgorithmException按定义抛出。

我的问题:在我的实现中,代码

   } catch (NoSuchAlgorithmException e) {
        LOGGER.fatal(MD_INIT_ERROR, e);
        return null;
   }

永远不会达到,所以我认为应该有更好的解决方案,可以避免(逻辑上和实际上)无法访问的代码。

欢迎任何解决方案/建议,谢谢。

编辑:

运行代码时这不是真正的问题。但是在测试中,由于代码不可达,再加上一些“try-catch with resources”,质量分析工具(sonar,pmd)会考虑代码“Insufficient branch coverage by unit tests”,这是目前的一大问题。分析报告,这就是为什么我想避免这段代码。

MessageDigest.getInstance(digestAlgo);另一个问题,在我的构造函数中测试是一个好习惯吗?还是让insert(File)自己承担全部责任更好NoSuchAlgorithmException

4

2 回答 2

1

这门课上发生的事情太多了。如果它是,顾名思义,一个文件存储库,它的重点应该是存储文件,但显然有很多不相关的活动围绕获取 MessageDigest 实例——应该是这个类的责任来创建一种隧道 (通过静态方法)对 MessageDigest 的依赖?有许多依赖注入选项,所有这些选项都使您能够将配置对象的责任转移到专用于该目的的框架(Spring、Guice、PicoContainer 等)。

我认为您已经认识到这里的问题,所以这是一个很好的开始。作为一项规则,您应该努力不抛出异常,通常对象构造函数是我最不喜欢这样做的地方之一。如果您使用框架来帮助您配置对象,那么您在这里所面临的尴尬就可以完全消失。此外,不是一次而是两次您返回 null ——它会让您在方法调用的另一端检查 null 并且您真的想要这样做吗?如果您考虑一下,我敢打赌您会想找到另一种方法(并且您确实有其他选择)。

此外,您会发现使用专门的对象创建工厂(即那些依赖注入框架就是这样)配置您的对象将帮助您更松散地将组件耦合在一起,这将提高独立于组件测试组件的可能性真正的依赖——使用模拟进行测试。如果你可以在你做任何其他事情之前改变你在哪里为你希望拥有的代码编写单元测试的想法,你应该期望看到更好的设计开始几乎无意识地发生。GOOS书是一个很好的入门资源。最好的祝愿!

编辑:我误读了——看起来你只返回一次 null ,但这仍然是一次太多。:-/

于 2014-01-31T04:40:15.603 回答
0

我想我会更改构造函数以采用 MessageDigest 而不是算法名称,并让调用者处理异常。但这里还有另一个问题。将摘要器作为实例成员意味着该类不是线程安全的。

于 2014-01-31T04:55:50.077 回答