这将是一个难以描述的问题,但现在可以了。
我们正在使用Delphi Spring Framework。 (http://code.google.com/p/delphi-spring-framework/)
假设我有UnitA声明由ClassA实现的InterfaceA。
同样,我有UnitB声明由ClassB实现的InterfaceB。
两者都在各自的初始化部分中使用Spring Container注册了他们的接口和类。
InterfaceA依赖于InterfaceB,但由于我们使用的是Spring,因此UnitA在其uses
子句中没有UnitB。换句话说,我们已经完成了我们的工作 - 我们已经将UnitA和UnitB分离,但我们仍然可以让InterfaceA依赖于InterfaceB。
但是,鉴于上述情况,我们需要确保UnitA和UnitB都包含在项目中,以便可以解决依赖关系。
想象一下,现在,我们开始一个新项目。该新项目使用UnitA,但开发人员没有意识到如果要使用UnitA,则还必须在项目中包含UnitB。不会出现编译器错误,因为依赖项是在运行时解决的,而不是编译时。
这就是一个问题:在应用程序部署之前,确保对UnitB的这种依赖性是否已知的正确方法是什么?
我们可以预见复杂应用程序中的情况,尽管进行了全面测试,但是可能很长时间没有执行给定的代码路径,并且在部署之前未发现此缺失的依赖关系。
我们已经实现了一个系统,其中每个接口解析调用都伴有Requires
调用,该调用在启动时检查并引发异常,确保我们会看到错误。但我们想知道是否有“最佳实践”或标准方法来检测此问题或以其他方式处理此问题。
已添加:这是Java和其他语言的问题吗?
答案 0 :(得分:5)
您需要使用Maven或Ivy等依赖关系管理解决方案。一旦你这样做,你就可以说UnitA依赖于UnitB,一旦有人将UnitA作为依赖项添加,该工具(Maven或Ivy)将被迫下载依赖项并将其包含在你的项目中。
Maven本身有一个Eclipse plugin,即使你当前的工作区已有另一个项目,它也能够检测到。
答案 1 :(得分:2)
我有点困惑。它使用的接口使您松散耦合而不是IoC容器。如果那是宣告InterfaceB的地方,UnitA将使用UnitB是唯一自然的。
接口的实现是另一回事。那些需要引用它们实现的接口以及它们使用的任何接口,但不应该引用任何其他实现。
我没有使用Spring for Delphi,但我熟悉其他IoC容器。如果它的行为类似,那么您将注册一个接口及其实现。当您调用resolve
时,您传入的是接口名称或其他有关接口的信息(类型信息),并希望IoC容器返回对您请求的接口的引用。该接口背后的实现取决于注册了哪些实现以及解决请求的规则。
如果您请求的界面从未注册,则会出现例外情况。一些IoC容器可以通过一次调用解析整个依赖链。
您要求在构建时确定是否在运行时解析依赖项,但在运行时之前不会注册依赖项。无论你使用什么工具,我都不认为可以保证。
UnitA 应在其uses子句中包含UnitB。 UnitA和UnitB中接口的实现可能并且可能应该位于与A和B分开的单元中,特别是如果每个接口有多个实现。
然后,在项目中使用UnitA的开发人员也将被迫在项目中包含UnitB。如果他们在新项目中使用测试驱动开发,他们会很快发现他们需要为InterfaceA和InterfaceB提供实现(即使它们只是模拟),以便他们的测试通过。
坦率地说,如果忽视了一个关键的依赖关系并且没有它就部署了项目,那么测试就不够彻底了。单元测试可能无法捕捉到这一点,但这正是一套集成测试通常会捕获的。
我建议使用Fit或Fitnesse之类的内容进行集成测试(虽然我不确定Fit4Delphi项目有多成熟)。任何可以编写word文档或编辑wiki的人都可以编写测试,开发人员只需编写允许测试驱动生产代码的类。如果设置正确,您可以针对项目的实际发布版本运行大多数集成测试。