如果不考虑场景,那么所有设计模式都有"把简单的东西搞复杂"之嫌啊.
依赖注入即使不依赖容器,也是好处大大的,比如方便做单元测试,不仅仅局限于以后好扩展.
如果用一个最简单的例子描述依赖注入,那依赖注入实际上和工厂模式的作用差不多(单纯负责类对象的创建), 例子:
// 当伪码用,不用关注语法
class IB {}
class B1 : public IB{}
class B2 : public IB{}
struct A {
A(IB *b) {}
}
// 一般处理
A *a1 = new A(new B1);
A *a2 = new A(new B2);
// 用工厂模式,A不想依赖IB的具体实现
// 省略工厂代码
A *a1 = new A(Factory::create("B1"))
A *a2 = new A(Factory::create("B2"))
// A需要依赖工厂类,工厂类以来IB的具体实现B1/B2
// 试试依赖注入容器怎么搞(API随便写的,各个容器库不一样)
IOCContainer ioc;
ioc.bind("B1");
ioc.bind("B2");
A *a1 = ioc.resolve("B1")
好,到这里,依赖注入完成了类似工厂模式的任务(对象创建),比工厂模式好用的地方是,对象之间的依赖关系比工厂模式用起来好多了,更像稳定可靠的配置易组装,比新增工厂类写代码好多了.
所以说简单的场景(类对象并不依赖很多类), 工厂模式(或者啥都不用)也是OK的,如果场景复杂,那么把这些依赖关系脱离业务代码之外配置好,那就是把复杂的问题剥离开了. 经常看到有些类是这样的:
struct Test {
Test(A *a, B* b, C *c, D *d):
a(A::create()),
b(B::create())....
c(C::create(new D()))
}
诸如此类,明显也不符合最少知识原则,作为客户端类Test需要知道被依赖的类细节太多了. 把这些都配置起来扫清很多负担,依赖各类接口就好.
c++项目中没怎么用过依赖注入容器,上面是我浅显的理解,有错误还请指出.
另外,有什么好用的c++依赖注入容器库推荐么,Boost.DI功能很强,用起来不好的地方在于有的错误发生在运行时了很难排查; 另外有一些库很简单,只支持装配一个类.