5 回答
TA贡献1807条经验 获得超9个赞
到目前为止,我发现的最佳定义是James Shore:
对于5美分的概念,“依赖注入”是一个25美元的术语。[...]依赖注入意味着为对象提供其实例变量。[...]。
目前由Martin Fowler的一篇文章,可能证明是有用的,太。
依赖注入基本上是提供对象所需的对象(其依赖关系),而不是让它自己构造它们。这是一种非常有用的测试技术,因为它允许模拟或删除依赖项。
可以通过多种方式(例如构造函数注入或setter注入)将依赖项注入到对象中。甚至可以使用专门的依赖注入框架(例如Spring)来做到这一点,但它们当然不是必需的。您不需要这些框架具有依赖注入。显式地实例化和传递对象(依赖关系)与框架注入一样好。
TA贡献1828条经验 获得超13个赞
依赖注入是一种实践,其中对象的设计方式是从其他代码段接收对象的实例,而不是在内部构造它们。这意味着可以替换实现对象所需的接口的任何对象而无需更改代码,这简化了测试并改善了解耦。
例如,考虑以下条款:
public class PersonService { public void addManager( Person employee, Person newManager ) { ... } public void removeManager( Person employee, Person oldManager ) { ... } public Group getGroupByManager( Person manager ) { ... }}public class GroupMembershipService() { public void addPersonToGroup( Person person, Group group ) { ... } public void removePersonFromGroup( Person person, Group group ) { ... }}
在这个例子中,执行PersonService::addManager
并且PersonService::removeManager
需要一个实例GroupMembershipService
才能完成它的工作。如果没有依赖注入,传统的方法是GroupMembershipService
在构造函数中实例化一个new ,PersonService
并在两个函数中使用该实例属性。但是,如果构造函数GroupMembershipService
有多个需要的东西,或者更糟糕的是,有一些初始化的“setter”需要调用GroupMembershipService
,代码增长得相当快,PersonService
现在不仅取决于GroupMembershipService
而且还取决于其他所有东西。GroupMembershipService
依赖于取决于。此外,链接到GroupMembershipService
硬编码,PersonService
这意味着你不能“假装”aGroupMembershipService
用于测试目的,或在应用程序的不同部分使用策略模式。
使用依赖注入,而不是实例化GroupMembershipService
你的内部PersonService
,你要么将它传递给PersonService
构造函数,要么添加一个Property(getter和setter)来设置它的本地实例。这意味着你PersonService
不再需要担心如何创建一个GroupMembershipService
,它只接受它给出的那些,并与它们一起工作。这也意味着任何作为接口的子类GroupMembershipService
或实现GroupMembershipService
接口的东西都可以“注入” PersonService
,并且PersonService
不需要知道变化。
TA贡献1963条经验 获得超6个赞
接受的答案是一个很好的答案 - 但我想补充一点,DI非常类似于代码中经典的避免硬编码常量。
当您使用某个常量(如数据库名称)时,您可以快速将其从代码内部移动到某个配置文件,并将包含该值的变量传递到需要它的位置。这样做的原因是这些常量通常比其余代码更频繁地更改。例如,如果您想测试测试数据库中的代码。
DI在面向对象编程领域类似于此。那里的值而不是常量文字是整个对象 - 但是将类代码从类代码中创建出来的代码的原因是相似的 - 对象的更改频率比使用它们的代码更频繁。需要进行此类更改的一个重要案例是测试。
添加回答
举报