7

这将是一个难以描述的问题,但这里有。

我们正在使用 Delphi Spring 框架。(http://code.google.com/p/delphi-spring-framework/)

假设我有一个 UnitA,它声明了由 ClassA 实现的 InterfaceA。

同样,我有 UnitB 声明由 ClassB 实现的 InterfaceB。

两者都在各自的初始化部分中向 Spring Container 注册了它们的接口和它们的类。

InterfaceA 依赖于 InterfaceB,但是因为我们使用的是 Spring,所以 UnitA 的子句中没有 UnitB uses。换句话说,我们已经完成了我们的工作——我们已经解耦了 UnitA 和 UnitB,但我们仍然能够让 InterfaceA 依赖于 InterfaceB。

但是,鉴于上述情况,我们需要确保 UnitA 和 UnitB 都包含在项目中,以便解决依赖关系。

现在想象一下,我们开始一个新项目。那个新项目使用了 UnitA,但开发者没有意识到如果要使用 UnitA,还必须在项目中包含 UnitB。不会出现编译错误,因为依赖是在运行时解决的,而不是编译时。

这里有一个问题:确保在部署应用程序之前知道对 UnitB 的这种依赖关系的正确方法是什么?

我们可以预见一个复杂应用程序中的情况,尽管经过彻底的测试,给定的代码路径可能很长时间都没有执行,并且在部署之前没有发现这种缺失的依赖关系。

我们已经实现了一个系统,其中每个接口解析调用都伴随着一个Requires调用,该调用在启动时检查并引发异常,确保我们会看到错误。但我们想知道是否有“最佳实践”或标准方法来检测或以其他方式处理此问题。

补充: 这是 Java 和其他语言的问题吗?

4

2 回答 2

5

您需要使用像MavenIvy这样的依赖管理解决方案。一旦你这样做了,你就可以说 UnitA 依赖于 UnitB,一旦有人将 UnitA 添加为依赖项,工具(Maven 或 Ivy)将被迫下载依赖项并将其包含在你的项目中。

Maven 本身有一个Eclipse 插件,即使您当前工作区中已经有另一个项目,它也能够检测到。

于 2011-08-31T12:49:16.147 回答
2

我有点困惑。它使用接口为您提供松散耦合,而不是 IoC 容器。如果这是声明 InterfaceB 的地方,那么 UnitA 将使用 UnitB 是很自然的。

接口的实现是另一回事。这些将需要引用他们实现的接口和他们使用的任何接口,但不应该引用任何其他实现。

我没有将 Spring 用于 Delphi,但我熟悉其他 IoC 容器。如果它的行为相似,那么您正在注册一个接口及其实现。当您调用时,resolve您正在传递接口的名称或有关接口的一些其他信息(类型信息),并期望 IoC 容器返回对您请求的接口的引用。该接口后面的哪个实现取决于注册了哪些实现以及为解决请求制定了哪些规则。

如果您请求的接口从未注册过,则会出现异常。一些 IoC 容器可以通过一次调用来解决整个依赖链。

您正在寻求一种方法来确定在构建时是否将在运行时解析依赖项,但依赖项直到运行时才注册。我认为无论您使用什么工具,都不能保证这一点。

UnitA在其使用条款中包含 UnitB。UnitA 和 UnitB 中的接口实现可以而且可能应该位于与 A 和 B 分开的单元中,尤其是在每个接口有多个实现的情况下。

然后,在项目中使用 UnitA 的开发人员也将被迫在项目中包含 UnitB。如果他们在新项目中使用测试驱动开发,他们会很快发现他们需要为 InterfaceA 和 InterfaceB 提供实现(即使它们只是模拟)才能通过测试。

坦率地说,如果忽略了一个关键依赖项并且在没有它的情况下部署了项目,那么测试就不够彻底。单元测试可能无法捕捉到这一点,但这正是一套集成测试通常会捕捉到的。

我会推荐FitFitnesse之类的东西进行集成测试(尽管我不确定Fit4Delphi项目有多成熟)。任何可以编写 word 文档或编辑 wiki 的人都可以编写测试,开发人员只需编写允许测试驱动生产代码的类。如果设置正确,您可以针对项目的实际发布版本运行大多数集成测试。

于 2011-08-31T18:47:24.570 回答