我的问题是专门处理通过构造函数的依赖注入。我了解服务定位器模式、构造函数/设置器注入及其风格的优缺点,但是在选择纯构造函数注入后,我似乎无法克服一些问题。在阅读了许多可测试设计的材料后,包括彻底阅读 Miško Hevery 的博客(特别是这篇文章)后,我处于以下情况:
假设我正在编写一个 C++ 程序,并且我已经通过它们的构造函数正确地注入了我的依赖项。为了可读性,我给了自己一个高级对象,它有一个从 main 调用的 Execute() 函数:
int main(int argc, char* argv[]) {
MyAwesomeProgramObject object(argc, argv);
return object.Execute();
}
Execute() 的职责是简单地连接所有需要的对象并启动最高级别的对象。最高级别的对象需要几个依赖项,这些对象需要一些对象等等,这意味着一个看起来像这样的函数:
MyAwesomeProgramObject::Execute() {
DependencyOne one;
DependencyTwo two;
DependencyThree three;
MidLevelOne mid_one(one);
MidLevelTwo mid_two(two, three);
// ...
MidLevelN mid_n(mid_dependencyI, mid_dependencyJ, mid_dependencyK);
// ...
HighLevelObject1 high_one(mid_one, mid_n);
HighLevelObject2 high_two(mid_two);
ProgramObject object(high_one, high_two);
return object.Go();
}
从我从 Miško 的博客中获得的内容(我会问他,但认为他没有时间回复我),这是满足纯构造函数注入依赖项的唯一方法。
在提到的博客文章中,他指出我们应该在每个对象的生命周期级别上都有工厂,但这本质上是 Execute 正在做的事情,使我的代码看起来与他的示例相同:
AuditRecord audit = new AuditRecord();
Database database = new Database(audit);
Captcha captcha = new Captcha();
Authenticator authenticator =
new Authenticator(database, captcha, audit);
LoginPage = new LoginPage(audit, authenticator);
问题:
- 这是正确的方法吗?
- 这是我不知道的模式吗(似乎类似于 Maven 的 context.xml)?
- 对于纯粹的构造函数注入,我是否只是承受“前期”分配的成本?