我正在使用Zend Framework构建MVC应用程序。该模型包括单独的Domain和Mapper层,Service层位于顶层。
对于我的一些Domain对象,当我创建一个新实例时,我需要创建由第一个对象组成的其他Domain对象。例如,当我创建一个新的Organization对象时,我可能会添加一个Employee对象(基于当前用户)和一个Location对象(基于当前用户的位置)。
到目前为止,我一直在父对象的构造函数中创建它们(在本例中为Organization)。这没关系,但它确实会在组织及其子女之间造成不必要的依赖。
我更愿意在服务层创建孩子,但如果我这样做,我是否会让自己陷入困境?
在阅读了关于服务层的Martin Fowlers(POEAA)章节之后,我认为这取决于这是域逻辑还是应用程序/工作流逻辑。在我看来它的边界......(请注意,我的服务层已不仅仅是一个外观)。
答案 0 :(得分:1)
正如我从您的描述中所理解的,目前Employee
和Location
都是Organization
的每个实例的必需依赖项。当你在构造函数中创建这个依赖项时,你在这里创建了两个问题(你有点像同一个丑陋的棍子的两端):
Organization
类与“员工”和“位置”的名称紧密相关
测试Organization
实例的行为变得非常困难,因为您无法直接控制其依赖关系。您无法隔离“受测试单元”。
注意A:实际上,组织需要一组员工/成员,最少一个。在这种情况下,域对象的集合似乎是逻辑和API实现的位方面的更好选择。
为了避免这些问题,当你必须创建一个复杂的对象图时,有两种解决方案:
使用工厂(由正确实施的DIC补充),在构建新实例时,它会创建Organization
类的所有要求并注入它们。
创建所有依赖项,然后在实例化对象时在Organization
中手动注入它们。
注意B:在服务中创建任何域对象,您应该使用工厂来处理所述对象。为此,您必须在实例化的任何服务的构造函数中注入域对象工厂。否则,您最终会得到与其他类名称相关联的类。
选择取决于你想对那个和类似案例中的 Employee
EmployeeCollection
和Location
个实例以及你的样式做什么偏爱。
如果您正在使用这些依赖项进行广泛且非常具体的操作,那么它们肯定应该单独实例化(通过简单的域对象工厂),然后才能进行注入。如果您只是创建一个对象图,那么基于DIC的工厂将是一个有利的解决方案。
P.S。:我建议您观看The Clean Code Talks - Don't Look For Things!讲座。