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

我们是否有效地利用国际奥委会?

  •  16
  • Juliet  · 技术社区  · 15 年前

    所以我的公司使用 Castle Windsor IoC container 但在某种程度上,感觉“不舒服”:

    • 所有数据类型都注册在代码中,而不是配置文件中。
    • 所有数据类型都经过硬编码以使用一个接口实现。事实上,对于几乎所有给定的接口,存在并且将永远只有一个实现。
    • 所有注册的数据类型都有一个默认的构造函数,因此温莎不会为任何注册的类型实例化对象图。

    设计该系统的人坚持使用IOC容器使系统更好。我们有1200多个公共课,所以 大的 系统,就是你想要的那种 期待 找到温莎那样的框架。但我仍然怀疑。

    我的公司使用IOC是否有效?有风的新物体比有风的新物体有优势吗? new 关键字?

    4 回复  |  直到 15 年前
        1
  •  23
  •   Community CDub    7 年前

    简短的回答: ,您的公司没有有效地使用DI。

    稍微长一点的答案:主要的问题是所有的类都有 默认构造函数 . 在这种情况下,如何解决依赖关系?

    您的构造函数或者具有这样的硬编码依赖项:

    public Foo()
    {
        IBar bar = new Bar();
    }
    

    在这种情况下,如果不重新编译该应用程序,就不能改变依赖项。

    更糟糕的是,他们可能会使用 Static Service Locator anti-pattern :

    public Foo()
    {
        IBar bar = Container.Resolve<IBar>();
    }
    

    DI容器应该解析应用程序的 Composition Root 别挡道。

    一般来说,最好用 配置上的约定 通过在代码中使用启发式方法来配置容器。XML配置应该为少数需要重新配置依赖项的情况保留。 无需重新编译 ,它应该只是一个子集。简而言之,我认为在代码中配置容器没有固有的问题。实际上,这是首选的方法。

    每个接口只有一个实现也不是问题。这是一个开始,如果应用程序是真正松散耦合的,那么它是 不断打开机遇之窗 . 迟早,您很可能会引入替代实现,但如果接口已经就位,并且整个代码基都遵循 Liskov Substitution Principle .

        2
  •  3
  •   Community CDub    7 年前

    所有数据类型都注册在代码中,而不是配置文件中。

    根据数据类型,我认为您指的是绑定。例如, IFoo 应该与 Foo . 如果是这样,那就好了。事实上,在许多人眼中(包括我在内),这比通过XML指定绑定要好得多。这里的自然好处是在编译时进行检查。你不会 XML编程 正如他们所说的。

    所有数据类型都是硬编码的 一个接口实现。事实上, 对于几乎所有给定的接口, 是和将永远是一个 实施。

    你确定?如果是这样的话 能够 闻一闻。不过,你已经说过这是一个很大的应用程序。如果正在进行任何单元测试(或自动测试),那么每个实现都有一个接口是完全有效的。

    我的公司使用IOC是否有效? 新宁有优势吗 有风的物体比新的 带有新关键字的对象?

    是的,据我所知。对于任何形式的自动化测试,在对象内创建依赖项都是一件糟糕的事情。通过使用IOC容器,可以在实际将生产代码连接在一起时移除类的复杂连接。这简化了应用程序,并允许作为开发人员的您专注于特性和其他任务,而不是确保实际构建整个东西。

    此外,通过反转控件,对应用程序的模块化部分进行更改非常容易。例如,假设您希望切换模块以获得更好的版本。使用IOC容器,您只需修改一行或两行绑定。如果没有IOC,您必须手动遍历应用程序,并确保其内部连接正确。

    这是一个与你最后一点有关的好问题,关于 why you should use IOC 直接人工方法。

        3
  •  1
  •   Roman    15 年前

    我相信其他人会贴出更详细的答案,但我有:

    所有数据类型都注册在代码中,而不是配置文件中。

    有一种趋势( at least some )使用代码而不是XML配置来注册依赖项的IOC/Dependency注入框架。主要的好处是,在编译时,您知道是否有错误的连接。例如,如果您决定添加/删除一个构造函数参数,那么当您的配置不同步时,您的代码实际上不会编译(并且它会防止打字错误在运行时显示为随机的空引用异常)。

    所有数据类型都经过硬编码以使用一个接口实现。事实上,对于几乎所有给定的接口,存在并且将永远只有一个实现。

    我不太确定“一个接口实现”是什么意思。如果您的意思是接口向下投射到实现它们的对象上,那么这绝对不是犹太洁食。如果不是这样,那么编码到接口而不是具体的实现是有好处的。主要的功能显然是能够在单元测试中使用支持所述接口的模拟对象。编程到接口(理论上)迫使您使代码更松散地耦合,这有助于测试性。它还打开了一些非常酷的设计选项,比如这个 Build a generic typesafe DAO with Hibernate and Spring AOP 一个。

    所有注册的数据类型都有一个默认的构造函数,因此温莎不会为任何注册的类型实例化对象图。

    这也不一定是坏事。我认为一般来说,经验法则是,如果依赖关系对于类执行其函数至关重要,那么应该使用构造函数注入。如果不是(日志记录可能是最常用的例子),那么属性注入是一个更合适的选项。虽然我不熟悉CaseWistor,但我知道至少有些Java IOC容器不支持早期版本中的构造函数注入(如果熟悉CaseWistor的人可以对此发表评论,那太棒了)。如果Castle Windsor在早期版本中没有此功能,这也可能导致您在系统中看到的设计。

    就使用IOC和呼叫而言 new 在任何地方,这也取决于使用情况。我所做的几个项目都依赖于IOC(Java中的Spring和.NET中的AutoFac),在一个地方把我所有的依赖关系连接起来,使我们能够快速而无痛苦地对对象层次结构和组成进行实验。

        4
  •  0
  •   Frank Schwieterman    15 年前

    你的前两个问题不是真正的问题(finglas描述了原因)。

    我认为“所有注册的数据类型都有一个默认的构造函数”是一种代码味道(假设类直接从IOC容器加载依赖项)。当发生这种情况时,其1)一个应用程序入口点,在该入口点可以从IOC容器中获取对象(无论如何,您可能需要初始化该IOC容器),或2)一个可以使用工厂的地方。

    不鼓励使用默认的构造函数填充依赖项。原因是你在复制如何创建类的知识。理想情况下,每个类甚至不必知道IOC容器在哪里——这是应用程序入口点的工作。

    听起来你们公司的IOC使用总体上还不错。