依赖注入是否违反OOP?

时间:2012-02-27 07:19:47

标签: interface dependency-injection

我觉得使用依赖注入正在改变我编写面向对象代码的方式。例如,下面是我没有DI

的情况
Interface: DataAdapter
SqliteDataAdapter implements DataAdapter
XMLDataAdapter    implements DataAdapter
OracleDataAdapter implements DataAdapter

// Initialization
DataAdapter adapter = new SqliteDataAdapter();
DataAdapter adapter = new XMLDataAdapter();
DataAdapter adapter = new OracleDataAdapter();

但使用DI我的代码结构将是:

Interface: DataAdapter
SqliteDataAdapter implements ISqliteDataAdapter,  DataAdapter
XMLDataAdapter    implements IXMLDataAdapter, DataAdapter
OracleDataAdapter implements IOracleDataAdapter, DataAdapter

// Initialization
ISqliteDataAdapter adapter = new SqliteDataAdapter();
IXMLDataAdapter    adapter = new XMLDataAdapter();
IOracleDataAdapter adapter = new OracleDataAdapter();

这种改变的原因是在我的模块中我可以将1个接口绑定到1个类。 这是一种不好的做法吗?如果是,那么正确的解决方案是什么?

DI不会改变使用接口的整个目的吗?

修改 以下是我对DI容器的绑定

bind(ISqliteDataAdapter.class).to(SqliteDataAdapter.class);
bind(IXMLDataAdapter.class).to(XMLDataAdapter.class);
bind(IOracleDataAdapter.class).to(OracleDataAdapter.class);

如果按照建议操作,我怎么能使用多个适配器?如果我需要在我的应用程序中同时使用XMLDataAdapter和SQLDataAdapter,该怎么办?

bind(DataAdapter.class).to(SqliteDataAdapter.class);

修改

以下是获取实例的当前调用:

@inject protected ISqliteDataAdapter dataAdapter;

以下是我应该只使用1个界面的方法:

@inject protected DataAdapter dataAdapter;
// In this case I don't have a choice on which type of data adapter It's going to create
// It's already defined in my module file and it's pointing to one of the 3 DataAdapters

所以我想要了解的是,如何以一种我可以控制它所注入的对象类型的方式构建我的代码,而不需要为每种类型的DataAdapter提供接口。

2 个答案:

答案 0 :(得分:5)

我会说DI是接口的自然结果。我们有接口的原因是我们可以编写不依赖于特定类的代码,而是编写具有多个类而无需任何更改的代码。即使我们期望只有一个我们需要的课程,这可能会在将来发生变化。通过编程到界面,我们甚至可以解释我们无法想象的变化。

DI只是以一种特殊的方式使用上述概念,以最大限度地提高代码的可测试性和适应性。所以我会说DI是真正的良好做法。

那就是说,我认为对于涉及这类系统的任何人都会发出一个警告。我们编写像SqliteDataAdaptor这样的完整类,然后按“提取界面”按钮给出ISqliteDataAdaptor界面是很危险的。这种做法非常坏,特别是如果它发生了很多。相反,ISqliteDataAdaptor通常应首先设计,然后才能编写合理的实现。

答案 1 :(得分:1)

依赖注入是关于控制实例化的内容并将该逻辑放在一个地方。您编写的代码不应更改您使用的基本类型(接口)。

在这两种情况下,您都应该使用DataAdapter作为您使用的对象类型。 谁决定从依赖注入容器而不是容器中获取实例的类型。

另见this