我应该使用依赖注入或不为了有一个良好的设计和可测试的代码

Should I use Dependency Injection or not in order to have a good design and testable code?

本文关键字:代码 测试 有一个 依赖 注入 我应该      更新时间:2023-10-16

我有一个代表图像的类:它叫做Photography

构造函数如下:

Photography::Photography(QString originalPath, QString appDirectory) {
    this.originalPath = originalPath;
    this.appDirectory = appDirectory;
}

该类包含getTitle()getCaption()getSize()isHorizontal()等多种方法

有一个public方法叫做getThumbnailPath(),它看起来像这样:

QString Photography::getThumbnailPath() {
    if (previewPath == "") {
        previewPath = appDirectory + "//cache//"+  getHash() +"-thumb.jpg";
    }
    return previewPath;
}

这个方法在内部调用getHash()方法:

QString Photography::getHash() {
    if (myHash == "") {
        QCryptographicHash hash(QCryptographicHash::Md5);
        QByteArray result = hash.hash(originalPath.toUtf8(), QCryptographicHash::Md5);
        QString hashResult(result.toHex());
        myHash  =  hashResult;
    }
    return myHash;
}

我想知道的是getHash()方法是否属于Photography类,或者应该在自己的HashGenerator中,我应该注入Photography类。

然而,我不想在Photography构造函数中注入很多参数,只是为了使类可测试。

在这种情况下,我正面临getThumbnailPath()方法的测试,如果我没有控制生成哈希的方法,我就不能测试getThumbnailPath()方法。

"然而,我不想仅仅为了使类可测试而在Photography构造函数中注入大量参数。"

可测试是任何代码段的良好质量。但更重要的是,您将解耦责任,并通过将哈希与哈希生成器关联使代码更易于维护。

这也意味着你现在可以独立地测试哈希而不需要类摄影。它现在是单元可测试的散列给出了一个路径,例如不涉及摄影

我认为将哈希代码从Photography类中取出是一个好主意,您可以独立测试,但我不会急于将该依赖项注入Photography,除非您需要多个哈希算法的实现。

我认为Photography类依赖于哈希代码是可以的,这可能是像自由函数一样简单的东西。哈希算法已经通过getThumbnailPath成员函数有效地公开了,所以我不认为在getThumbnailPath的测试中生成预期的哈希有什么特别的问题。

你应该给出所有你需要改变从外部[上下文独立性] (在创建时使用构造函数或使用setter方法)。当你使用设置方法时,你应该在构造函数中提供一个默认实例(而不是通过参数)——依赖项(没有这些对象,构造的对象就没有意义)应该通过构造函数提供。其他可以通过setter给出。

注意:如果你必须在构造函数中提供太多的helper对象,那么可能对该对象有太多的责任。你应该考虑改变设计。(我认为构造函数中超过8,9个参数需要重新设计)

我也认为你需要改变的不是哈希的计算方式。你需要改变的是ThumbnailPath的计算方式。因此,您应该使用如下的接口:

public interface ThumbnailGenerator{ //give a mock for the ThumbnailGenerator at testing.
  public ThumbnailPath generatePath(Object argumentToUseInGeneration);
}
不是

public interface HashGenerator{
  public Object generateHash(Object argument);
}

注意:在java中,哈希计算是在对象本身内进行的,因为哈希计算取决于对象的状态。(你可以在计算哈希时传递一个helper对象,但是哈希方法在对象内)