1

我正在使用 Zend Framework 构建一个 MVC 应用程序。该模型包括单独的域和映射器层,服务层位于顶部。

对于我的一些域对象,当我创建一个新实例时,我需要创建由第一个对象组成的其他域对象。例如,当我创建一个新的组织对象时,我可能会添加一个 Employee 对象(基于当前用户)和一个 Location 对象(基于当前用户的位置)。

到目前为止,我一直在父对象的构造函数中创建这些(在本例中为组织)。这没关系,但是它确实在组织和它的孩子之间创建了不必要的依赖关系。

我更愿意在服务层中创建孩子,但是如果我这样做,我会让自己陷入困境吗?

在阅读了关于服务层的 Martin Fowlers (POEAA) 章节后,我认为这归结为这是领域逻辑还是应用程序/工作流逻辑。在我看来,它是边界线......(请注意,我的服务层已经不仅仅是一个门面)。

4

1 回答 1

1

正如我从您的描述中了解到的,目前EmployeeLocation都是Organization. 当你在构造函数中创建这个依赖时,你会在这里创建两个问题(你有点像同一根丑陋的棍子的两端):

  • 该类Organization与“Employee”和“Location”的名称紧密耦合

  • 测试实例的行为变得非常困难Organization,因为您无法直接控制它的依赖关系。您无法隔离“待测单元”

注 A:实际上一个组织需要一组员工/成员,最少一个。在这种情况下,从逻辑和 API 实现的位方面来看,域对象的集合似乎是一个更好的选择。

为避免这些问题,当您必须创建复杂的对象图时,有两种解决方案:

  1. Organization在构建新实例时,使用工厂(由正确实施的 DIC 补充)创建类的所有需求并注入它们。

  2. 创建创建所有依赖项,然后Organization在实例化对象时手动将它们注入。

注意 B:要在服务中创建域任何域对象,您应该为所述对象使用工厂。为了促进这一点,您必须在您实例化的任何服务的构造函数中注入域对象工厂。否则,您最终只会得到与其他类的名称耦合的类。

选择将取决于您想在该情况和类似情况下对和实例做什么,以及您喜欢哪种风格。Employee EmployeeCollectionLocation

如果您正在对这些依赖项进行广泛且非常具体的操作,那么绝对应该单独实例化它们(通过简单的域对象工厂),然后才注入。如果您只是创建一个对象图,那么基于 DIC 的工厂将是有利的解决方案。

PS:我建议您观看The Clean Code Talks - Don't Look For Things!演讲。

于 2013-02-12T23:11:50.220 回答