我觉得使用依赖注入正在改变我编写面向对象代码的方式。例如,下面是我没有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提供接口。
答案 0 :(得分:5)
我会说DI是接口的自然结果。我们有接口的原因是我们可以编写不依赖于特定类的代码,而是编写具有多个类而无需任何更改的代码。即使我们期望只有一个我们需要的课程,这可能会在将来发生变化。通过编程到界面,我们甚至可以解释我们无法想象的变化。
DI只是以一种特殊的方式使用上述概念,以最大限度地提高代码的可测试性和适应性。所以我会说DI是真正的良好做法。
那就是说,我认为对于涉及这类系统的任何人都会发出一个警告。我们编写像SqliteDataAdaptor
这样的完整类,然后按“提取界面”按钮给出ISqliteDataAdaptor
界面是很危险的。这种做法非常坏,特别是如果它发生了很多。相反,ISqliteDataAdaptor
通常应首先设计,然后才能编写合理的实现。
答案 1 :(得分:1)
依赖注入是关于控制实例化的内容并将该逻辑放在一个地方。您编写的代码不应更改您使用的基本类型(接口)。
在这两种情况下,您都应该使用DataAdapter作为您使用的对象类型。 你谁决定从依赖注入容器而不是容器中获取实例的类型。
另见this