这是对Doc Brown的补充回答,也是对Dinaiz仍与该问题相关的未回答评论的回应。
您可能需要的是进行DI的框架。具有复杂的层次结构并不一定意味着设计不好,但是如果您必须自下而上地注入TimeFactory(从A到D),而不是直接注入D,那么您进行依赖注入的方式可能有问题。
一个人吗?不用了,谢谢。如果您只需要一个等距使其在整个应用程序上下文中共享(使用像Infector ++这样的DI的IoC容器只需要将TimeFactory绑定为单个等距),下面就是示例(顺便说一下C ++ 11,但是C ++。到C ++ 11了吗?您可以免费获得Leak-Free应用程序):
Infector::Container ioc; //your app's context
ioc.bindSingleAsNothing<TimeFactory>(); //declare TimeFactory to be shared
ioc.wire<TimeFactory>(); //wire its constructor
// if you want to be sure TimeFactory is created at startup just request it
// (else it will be created lazily only when needed)
auto myTimeFactory = ioc.buildSingle<TimeFactory>();
现在,IoC容器的好处是您不需要将时间工厂传递给D。如果您的类“ D”需要时间工厂,只需将时间工厂作为类D的构造函数参数即可。
ioc.bindAsNothing<A>(); //declare class A
ioc.bindAsNothing<B>(); //declare class B
ioc.bindAsNothing<D>(); //declare class D
//constructors setup
ioc.wire<D, TimeFactory>(); //time factory injected to class D
ioc.wire<B, D>(); //class D injected to class B
ioc.wire<A, B>(); //class B injected to class A
如您所见,您只注入了一次TimeFactory。如何使用“ A”?非常简单,每个类都可以注入,建立在主体中或由工厂负责。
auto myA1 = ioc.build<A>(); //A is not "single" so many different istances
auto myA2 = ioc.build<A>(); //can live at same time
每次创建类A时,它将自动(懒惰)注入所有依赖项,直到D,并且D将注入TimeFactory,因此,仅调用1个方法就可以准备完整的层次结构(甚至可以通过这种方式解决复杂的层次结构删除很多样板代码):您不必调用“ new / delete”,这非常重要,因为您可以将应用程序逻辑与粘合代码分开。
D可以使用仅D可以拥有的信息来创建Time对象
这很容易,您的TimeFactory有一个“创建”方法,然后只需使用其他签名“创建(参数)”就可以完成。不依赖项的参数通常以这种方式解析。这也消除了注入诸如“弦”或“整弦”之类的东西的责任,因为这只会增加额外的锅炉板。
谁创造谁?IoC容器创建等距物和工厂,工厂创建其余物(工厂可以创建具有任意参数的不同对象,因此您实际上不需要工厂的状态)。您仍然可以将工厂用作IoC容器的包装器:一般而言,在IoC容器中注入Injectin非常糟糕,与使用服务定位器相同。某些人通过用工厂包装IoC容器解决了这个问题(这不是严格必要的,但优点是容器可以解决层次结构,并且您所有的工厂都变得更加易于维护)。
//factory method
std::unique_ptr<myType> create(params){
auto istance = ioc->build<myType>(); //this code's agnostic to "myType" hierarchy
istance->setParams(params); //the customization you needed
return std::move(istance);
}
同样不要滥用依赖注入,简单类型可以只是类的成员或局部范围的变量。这似乎很明显,但是我看到人们注入“ std :: vector”只是因为有一个允许这样做的DI框架。永远记住Demeter的定律:“只注入您真正需要注入的东西”