Questions tagged «dependency-injection»

依赖注入是一种设计模式,其中通过构造函数,方法或字段(属性)设置组件的依赖关系(对象的实例,属性)。它是更一般的依赖项反转的一种特殊形式。

13
那么Singletons不好,那又如何呢?
最近,关于使用(和过度使用)Singleton的问题进行了很多讨论。我也是我职业生涯早期的那些人之一。我可以看到问题出在哪里,但是,在许多情况下,我看不到一个很好的选择-而且,很少有反辛格尔顿的讨论真正提供过这样的讨论。 这是我参与的一个近期重大项目的真实示例: 该应用程序是一个胖客户端,具有许多单独的屏幕和组件,它们使用来自服务器状态的大量数据,这些数据并不经常更新。该数据基本上被缓存在Singleton“管理器”对象中-可怕的“全局状态”。想法是在应用程序中拥有一个位置来保存和同步数据,然后打开的任何新屏幕都可以从那里查询它们的大部分需求,而无需从服务器重复请求各种支持数据。不断地向服务器请求会占用太多带宽-我说的是每周要多付数千美元的互联网账单,所以这是不能接受的。 除了基本具有这种全局数据管理器缓存对象之外,还有其他合适的方法吗?当然,此对象不一定要正式是“ Singleton”,但从概念上讲,成为一个对象确实有意义。这里有什么不错的清洁选择?

7
Spring框架做什么?我应该使用它吗?为什么或者为什么不?
因此,我正在用Java启动一个全新的项目,并正在考虑使用Spring。我为什么要考虑春季?因为很多人告诉我我应该使用Spring!认真地说,每当我试图让人们解释Spring到底是什么或做什么时,他们永远无法给我一个直接的答案。我已经在SpringSource网站上查看了这些介绍,它们要么真的很复杂,要么真的是针对教程的,它们都没有给我一个很好的主意,为什么我应该使用它,或者它如何使我的生活更轻松。有时人们会抛出“依赖注入”这个术语,这使我更加困惑,因为我认为我对该术语的含义有不同的理解。 无论如何,这里有一些关于我的背景和我的应用程序的信息: 在Java中开发了一段时间,从事后端Web开发。是的,我进行了大量的单元测试。为了实现这一点,我通常制作(至少)一种方法的两个版本:一个使用实例变量,一个仅使用传递给该方法的变量。使用实例变量的一个调用另一个,提供实例变量。当进行单元测试时,我使用Mockito模拟对象,然后调用不使用实例变量的方法。这就是我一直以来所理解的“依赖注入”。 从CS的角度来看,我的应用程序非常简单。小型项目,需要1-2个开发人员。通常是CRUD类型的操作,并附带大量搜索。基本上是一堆RESTful Web服务,再加上Web前端,最后是一些移动客户端。我正在考虑使用直接的HTML / CSS / JS / JQuery进行前端,因此没有真正的计划使用JSP。使用Hibernate作为ORM,并使用Jersey来实现Web服务。 我已经开始编码,非常渴望在那里获得一个演示,我可以四处逛逛,看看是否有人想投资。因此,显然时间至关重要。我了解到Spring具有相当的学习曲线,而且看起来它需要一堆XML配置,而我通常会尽量避免这种麻烦。但是,如果这可以使我的生活更轻松,并且(尤其是)可以使我的生活和开发速度更快,那么我愿意痛不欲生,学习Spring。 所以,请。教我 我应该使用Spring吗?为什么或者为什么不?


8
依赖注入的批评和弊端
依赖注入(DI)是一种众所周知的流行模式。大多数工程师都知道它的优点,例如: 使单元测试中的隔离变得可能/容易 明确定义一个类的依赖 促进良好的设计(例如,单一职责原则(SRP)) 启用快速(开关实现DbLogger的,而不是ConsoleLogger例如) 我认为业界普遍认为DI是一种很好的有用模式。目前没有太多批评。社区中提到的缺点通常很小。他们中的几个: 增加班数 创建不必要的接口 目前,我们与同事讨论建筑设计。他相当保守,但思想开放。他喜欢质疑一些我认为很好的事情,因为IT领域中的许多人只是复制最新趋势,重复优势,而且通常不会考虑太多-不要分析得太深。 我想问的是: 只有一个实现时,应该使用依赖注入吗? 我们应该禁止创建除语言/框架对象之外的新对象吗? 如果我们不打算对特定的类进行单元测试,那么注入单个实现是个坏主意(假设我们只有一个实现,因此我们不想创建“空”接口)吗?


9
了解依赖注入
我正在阅读有关依赖项注入(DI)的信息。对我来说,这是一件非常复杂的事情,因为我在阅读它的同时也提到了控制反转(IoC),因此我感到自己将要经历一段旅程。 这是我的理解:不是在也使用它的类中创建模型,而是将模型(已经填充了有趣的属性)传递(注入)到需要它的地方(到新的类,该类可以将其用作参数)。构造函数)。 对我来说,这只是在争论。我一定想念小姐的意思吗?也许随着更大的项目变得更加明显? 我的理解是非DI(使用伪代码): public void Start() { MyClass class = new MyClass(); } ... public MyClass() { this.MyInterface = new MyInterface(); } DI将是 public void Start() { MyInterface myInterface = new MyInterface(); MyClass class = new MyClass(myInterface); } ... public MyClass(MyInterface myInterface) { this.MyInterface = myInterface; } 我确定我在这里糊涂了,有人可以说些什么吗?

5
在容器中使用依赖项注入与使用服务定位器有什么区别?
我知道直接实例化类内部的依赖关系被认为是不好的做法。这是有道理的,因为这样做紧密地结合了所有内容,从而使测试变得非常困难。 我遇到的几乎所有框架似乎都倾向于使用容器进行依赖注入而不是使用服务定位器。通过允许程序员指定当类需要依赖时应返回哪个对象,两者似乎都实现了相同的目的。 两者有什么区别?为什么我要选择一个?

11
(为什么)单元测试不测试依赖项很重要?
我了解自动测试的价值,并在问题足够明确的地方使用它,以便我可以提出好的测试用例。但是,我注意到,这里和StackOverflow上的某些人只强调测试一个单元,而不是测试其依赖项。在这里我看不到好处。 为避免测试依赖性而进行的模拟/存根增加了测试的复杂性。它在生产代码中增加了人工灵活性/去耦要求,以支持模拟。(我不同意说这会促进良好设计的任何人。写额外的代码,引入诸如依赖注入框架之类的东西,或者以其他方式增加代码库的复杂性以在没有实际用例的情况下使事情变得更灵活/可插拔/可扩展/解耦是过度设计,而不是好的设计。) 其次,测试依赖项意味着使用其他输入的测试关键的底层代码,而不是那些编写测试的人明确想到的输入。通过在高级功能上运行单元测试而不嘲笑它所依赖的低级功能,我发现了低级功能中的许多错误。理想情况下,这些可以通过单元测试中的低级功能找到,但是总是会漏掉一些情况。 另一面是什么?单元测试不要同时测试其依赖关系真的很重要吗?如果是这样,为什么? 编辑:我可以理解模拟外部依赖项(如数据库,网络,Web服务等)的价值。(感谢Anna Lear激励我进行澄清。)我指的是内部依赖项,即其他类,静态函数等。没有任何直接的外部依赖关系。

18
依赖注入:如何出售
众所周知,我是依赖注入(DI)和自动化测试的忠实拥护者。我可以整天谈论它。 背景 最近,我们的团队刚刚获得了一个从头开始构建的大型项目。它是具有复杂业务需求的战略应用程序。当然,我希望它美观大方,对我而言意味着:可维护且可测试。所以我想使用DI。 抵抗性 问题出在我们的团队中,DI是禁忌。它被提出了几次,但是众神不赞成。但这并没有阻止我。 我的举动 这听起来可能很奇怪,但是第三方库通常不经我们的架构师团队批准(请考虑:“您不要谈论Unity,Ninject,NHibernate,Moq或NUnit,以免割伤您的手指”)。因此,我没有使用已建立的DI容器,而是编写了一个非常简单的容器。基本上,它在启动时连接了所有依赖项,注入了任何依赖项(构造函数/属性),并在Web请求结束时处置了所有可抛弃对象。它非常轻巧,可以满足我们的需求。然后我请他们进行审查。 响应 好吧,简而言之。我遭到了沉重的抵抗。主要论点是:“我们不需要在已经很复杂的项目中增加这种复杂性”。另外,“这不像我们将插入组件的不同实现”。而且,“我们希望保持简单,如果可能的话,只需将所有内容装入一个程序集。DI是一种无用的复杂性,没有任何好处”。 最后,我的问题 您将如何处理我的情况?我不能很好地表达自己的想法,我想知道人们将如何表达自己的观点。 当然,我假设像我一样,您更喜欢使用DI。如果您不同意,请说出原因,以便我能看到硬币的另一面。看到不同意的人的观点真的很有趣。 更新资料 谢谢大家的回答。它确实使事情成为现实。拥有另一双眼睛可以给您反馈非常好,十五岁的确很棒!这确实是一个很好的答案,可以帮助我从不同角度看待这个问题,但是我只能选择一个答案,所以我只选择投票率最高的一个。感谢大家花时间回答。 我认为现在可能不是实施DI的最佳时机,我们还没有做好准备。相反,我将致力于使设计可测试,并尝试提出自动化的单元测试。我知道编写测试是额外的开销,并且如果曾经确定额外的开销不值得,我个人仍然认为这是一个成功的情况,因为设计仍然可以测试。而且,如果将来进行测试或DI是一种选择,则设计可以轻松应对。

7
我应该使用依赖注入还是静态工厂?
在设计系统时,我经常面临使其他模块使用大量模块(日志记录,数据库访问等)的问题。问题是,如何将这些组件提供给其他组件。似乎有两个答案可能是依赖注入或使用工厂模式。但是,两者似乎都错了: 工厂使测试变得痛苦,并且不允许轻易交换实现。它们也不会使依赖关系变得明显(例如,您正在检查一个方法,而忽略了它调用的方法会调用使用数据库的方法的事实)。 Dependecy注入使构造函数的参数列表大量膨胀,并且在代码的所有部分涂上了污点。典型情况是一半以上类的构造函数如下所示(....., LoggingProvider l, DbSessionProvider db, ExceptionFactory d, UserSession sess, Descriptions d) 这是我遇到的一个典型情况:我有异常类,这些异常类使用从用户数据库中加载的错误描述,并使用在用户会话对象中具有用户语言设置参数的查询。因此,要创建一个新的异常,我需要一个描述,它需要一个数据库会话和一个用户会话。因此,我注定要在所有方法中拖动所有这些对象,以防万一我可能需要引发异常。 我该如何解决这个问题?

5
依赖注入:场注入与构造函数注入?
我知道这是一个热门辩论,关于最佳做法的观点会随着时间而改变。 我曾经在课堂上专门使用字段注入,直到开始在不同的博客(例如petrikainulainen和schauderhaft和fowler)上阅读有关构造函数注入的好处的信息。从那以后,我切换了方法,将构造函数注入用于必需的依赖项,将setter注入用于可选的依赖项。 但是,我最近与JMockit的作者(一个模拟框架)进行了辩论,在其中他认为构造函数和setter注入是不良做法,并表示JEE社区同意他的观点。 在当今世界上,是否有首选的注射方法?现场注入是首选吗? 在过去的几年中,从字段注入转换为构造函数注入后,我发现使用起来更加清晰了,但是我想知道是否应该重新审视我的观点。JMockit的作者(RogérioLiesenfeld)显然精通DI,因此鉴于他强烈反对构造函数/ setter注入,我感到有义务重新审视我的方法。

7
切换到SOLID后管理和组织大量增加的课程?
在过去的几年中,我们一直在缓慢地转换为逐渐更好的书面代码,每次只需几个小步骤。我们终于开始切换到至少与SOLID类似的东西,但是我们还没有到那儿。自从进行切换以来,开发人员最大的抱怨之一就是他们无法忍受同行审查和遍历数十个文件,而以前的每个任务只需要开发人员触摸5-10个文件即可。 在开始进行转换之前,我们的体系结构非常类似于以下内容(已授予,但又增加了一个或两个数量级的文件): Solution - Business -- AccountLogic -- DocumentLogic -- UsersLogic - Entities (Database entities) - Models (Domain Models) - Repositories -- AccountRepo -- DocumentRepo -- UserRepo - ViewModels -- AccountViewModel -- DocumentViewModel -- UserViewModel - UI 从文件的角度来看,所有内容都非常线性且紧凑。显然有很多代码重复,紧密耦合和令人头疼的问题,但是,每个人都可以遍历并弄清楚。完全的新手,从来没有像以前那样打开过Visual Studio的人,就可以在几周内解决这个问题。缺乏整体文件的复杂性,对于新手开发人员和新员工来说,在不增加太多时间的情况下就开始进行贡献相对容易。但这几乎就是代码风格的任何好处都无法体现的地方。 我全心全意地支持我们为改善代码库所做的一切尝试,但是在这样的大规模范式转换中,从团队的其他成员那里得到一些回击是很普遍的。当前几个最大的症结是: 单元测试 班数 同行评审的复杂性 单元测试对于团队来说是一笔难以置信的辛苦卖点,因为他们所有人都认为这是浪费时间,并且他们能够比单个代码更快地整体测试代码。使用单元测试作为SOLID的认可在大多数情况下是徒劳的,并且在这一点上已经成为一个笑话。 上课人数可能是要克服的最大障碍。过去需要5-10个文件的任务现在可以占用70-100!尽管每个文件都有不同的用途,但文件的数量却是巨大的。团队的反应主要是吟和头部抓挠。以前,一项任务可能需要一个或两个存储库,一个或两个模型,一个逻辑层和一个控制器方法。 现在,要构建一个简单的文件保存应用程序,您需要一个类来检查文件是否已存在,一个类来编写元数据,一个类来进行抽象,DateTime.Now以便您可以投入时间进行单元测试,为每个包含逻辑的文件插入接口,包含每个类的单元测试,以及一个或多个文件以将所有内容添加到您的DI容器中。 对于中小型应用程序,SOLID非常容易出售。每个人都看到了可维护性的好处和便利。但是,他们只是没有看到SOLID在超大型应用程序中具有很好的价值主张。因此,我正在尝试寻找改善组织和管理的方法,以使我们度过不断增长的痛苦。 我以为基于最近完成的任务,可以更详细地说明文件量的示例。我被赋予一项任务,以在我们的一种较新的微服务中实现某些功能,以接收文件同步请求。收到请求后,服务将执行一系列查找和检查,最后将文档以及2个单独的数据库表保存到网络驱动器。 要将文档保存到网络驱动器,我需要一些特定的类: - …

3
什么是构造函数注入?
在浏览有关(服务定位器)设计模式的文章时,我一直在研究构造函数注入和依赖注入这两个术语。 当我搜索构造函数注入时,我得到的结果不清楚,这促使我在这里进行检查。 什么是构造函数注入?这是一种特定类型的依赖项注入吗?一个典型的例子将有很大的帮助! 编辑 一周的时间后,我又重新审视了这个问题,我看到自己迷失了……万一其他人突然出现在这里,我将通过一点我的学习来更新问题的正文。请随时发表评论/纠正。 构造函数注入和属性注入是两种类型的依赖注入。


7
什么时候不应用依赖倒置原则?
我目前正在尝试弄清SOLID。因此,依赖倒置原则意味着任何两个类都应该通过接口而不是直接进行通信。示例:如果class A有一个方法,该方法需要一个指向类型的对象的指针class B,则该方法实际上应在一个类型为对象的对象abstract base class of B。这对打开/关闭也有帮助。 如果我理解正确,那么我的问题是将其应用于所有类交互是一种好习惯还是应该尝试从层次上考虑? 我对此表示怀疑是因为我们为遵循这一原则付出了一些代价。说,我需要实现feature Z。经过分析,我的结论是功能Z包含的功能A,B和C。我创建了一个门面类Z,即,通过接口,使用类A,B和C。我开始编码的实施,在某些时候我意识到,任务Z实际上是由功能性A,B和D。现在,我需要取消C界面,C类原型并编写单独的D界面和类。如果没有接口,则只需要替换该类。 换句话说,要更改某些内容,我需要更改1.调用者2.接口3.声明4.实现。在python直接耦合的实现中,我只需要更改实现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.