代码之家  ›  专栏  ›  技术社区  ›  Pup

何时使用依赖注入?什么时候不去?

  •  11
  • Pup  · 技术社区  · 15 年前

    使用依赖注入似乎(总是?)更加解耦,但没有依赖注入(对许多人来说)更简单。

    从我对生活中每件事的理解来看,没有什么是绝对的,每件事都有时间和地点。我试图理解这里的权衡。

    4 回复  |  直到 15 年前
        1
  •  6
  •   Dean Johnston    15 年前

    正确地(有效地?)进行依赖项注入时,肯定会使对象解耦。在我看来,当您在单元测试中使用Mock或stub对象时,这一好处最容易实现。这通常意味着在每个单独的测试中,您将减少单元测试,从而使它们更简单。这种有效单元测试的推广通常会带来额外的好处。

        2
  •  5
  •   Robert Harvey    15 年前

    当您想要创建给定服务类型的替代实现时,请使用依赖项注入。这方面的典型示例是用模拟对象代替服务提供者进行测试。

    例如,依赖项注入允许您使用“真实”数据库或模仿真实数据库行为的“假”数据库。在这两种情况下,“注入”的依赖项具有相同的接口,但您可以交换掉实现。

        3
  •  2
  •   Nick Bedford    15 年前

    在实践中,我发现基于依赖注入的设计虽然稍显冗长,但更容易处理,因为有更多的控制,类之间的耦合更少,实现更灵活,并允许在整个应用程序中更广泛地使用现有类。

    这也取决于依赖关系的定义是否清晰或直观。我从本地C++背景中找到了.NET中的部分,其中依赖关系在这里显而易见,并且提供了很多灵活性,但是其他一些地方我根本不理解,不能立即理解使用某段代码或对象的要求,由于各种因素,包括类命名和我对系统的了解。

    我说,如果您要在设计代码时考虑到依赖项注入,请尽量使依赖项尽可能清晰直观。

    无论如何,这是我的想法。

        4
  •  0
  •   Steven Huwig    15 年前

    “依赖注入”涵盖的范围很广,从传入构造函数参数到XML配置的框架。我最近“发现”的一个快乐媒介涵盖了许多“模拟”案例,而不需要实际的框架。它有点颠覆性,但在孤立的情况下更容易使用。

    在主代码中重写工厂方法,以使用伪造的服务运行测试。基本上,这是滥用继承(使用此方法)和滥用配置(使用框架)之间的折衷。不管是“依赖注入”,还是我们在现实世界中喜欢称之为参数化。

    主要代码:

    public class A {
        // ...
        private service;
    
        protected Service getService() {
            return new RealService();
        }
    
        public A() {
            service = getService();
        }
        // ...
    }
    

    public class Test {
        void test() {
            final Service fakeService = new FakeService();
            A thingToTest = new A() { 
                protected Service getService() { return fakeService; }
            }
            thingToTest.doOneThing();
            // ...
        }
    }