我应该使用依赖注入或不为了有一个良好的设计和可测试的代码
Should I use Dependency Injection or not in order to have a good design and testable code?
我有一个代表图像的类:它叫做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对象,但是哈希方法在对象内)
- C++代码以测试另一个.cpp如果可以编译它
- 我如何测试代码没有调用 exit()
- 如何在使用 C 函数时测试C++代码
- 谷歌基准测试,如何只调用一次代码?
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- 使用 bash 脚本和测试处理进行代码编辑
- 使用 std::chrono::steady_clock 对线程/异步中的代码进行基准测试
- 使用 googletest 测试嵌入式C++代码时处理外设寄存器的重复符号
- 编写可测试的代码 - lambda 函数和unique_ptr中的basic_istream工厂
- 用于查找连续子数组的最大总和的代码使测试用例失败
- 外部 "C" Visual Studio 2015 中的显式类型错误,DLL 测试代码
- 如何对嵌入式代码进行单元测试?
- std::sort / 适用于测试代码,但无法推断出模板
- 有什么方法可以从Visual Studio 2017中的Catch C++测试中获取代码覆盖率指标?
- 用于 JUnit 测试的本机代码未使用 'nar-maven-plugin' 编译
- 如何避免使用IFDEF使代码更具测试
- 使用示例代码测试 mongocxx c++ 驱动程序
- 如何根据头文件中定义的代码测试类
- 工作与现有的c++代码测试下的谷歌测试和添加Qt
- 漂亮的打印 - 使用格式不正确的C++代码测试漂亮的打印机