【问题标题】:In the model layer, is it a good idea to compose types with IDs, as opposed to direct references?在模型层中,使用 ID 组合类型而不是直接引用是个好主意吗?
【发布时间】:2014-05-21 15:04:35
【问题描述】:

虽然这个问题是在 MVVM 的背景下进行的,但我认为它可以推广到任何 MV* 架构。

在创建模型层时,我习惯于直接引用对象来表示关系,例如:

class Course {
 CourseID ID { get; }
 string Name { get; }
}
class Student {
 IEnumerable<Course> EnrolledCourses { get; }
} 

但是,我发现从存储中重建此类对象层次结构变得越来越繁重。如果在模型层没有 DI 的好处,我将面临不愉快的选择:使用带有所有伴随属性和其他令人头疼的重型 ORM,或者使用微 ORM(我的偏好),然后煞费苦心地重建对象图手工。

我正在考虑完全放弃直接引用的想法,转而支持以下内容:

class Course {
 CourseID ID { get; }
 string Name { get; }
}
class Student {
 IEnumerable<CourseID> EnrolledCourses { get; }
} 

通过这种方式,我的模型层开始更接近于关系数据,我一直认为这在传统上是不受欢迎的(因此偏爱 ORM)。

在我的代码中,应用程序的数据通常通过 Repository 模式暴露给更高级别,作为响应式提要和/或 iEnumerables。这使得通过查询和/或按键过滤器按需检索和显示相关数据变得非常容易。不像直接参考那么容易,但很接近。

那么 - 反对在不引用其他类型的情况下建模域对象的主要论点是什么?另外,我试图找到有关此的讨论,但没有看到太多,可能是我缺少正确的搜索词吗?

【问题讨论】:

    标签: c# oop model composition


    【解决方案1】:

    在您希望可维护的任何应用程序中,您都需要尊重关注点分离。 MV* 始终是 UI 层的一部分,并且大多数时候您还拥有业务(域)层和持久层 (DAL)。

    SoC 意味着您可以同时专注于一层。 ViewModel 是为 View 设计的,Domain 模型只关心业务,Persistence Model 只关心保存和查询。这些是相关的,但不相同,最好将它们视为不同的。

    当您对域进行建模时,您并不关心其他层,您希望最好地表示业务概念(这非常棘手,因为其中很多似乎很容易建模,但这是一个陷阱!)以及这些概念的用例。这里没有任何参考,只有使用业务概念的业务流程,也就是说,即使您正在编写代码,您也应该从更高的层面而不是技术层面进行思考。

    例如,您向我们展示的代码确实看起来像一个视图模型,因为 Student 的域概念可能不涉及课程(您的视图需要它们一起使用)。您有 Student、Course,这两个概念协同工作用于许多业务场景。拥有一项旨在为学生注册课程的服务可能会更好(我不知道您的域的确切详细信息)。

    从持久性的角度来看,您可能拥有注册学生的存储库,即 CourseId 和 StudentId 的集合。可能我上面提到的服务如果不包含业务逻辑,可以直接在持久化中实现。几乎所有的设计决策都需要对领域有正确的理解,所以我在这里只是猜测,但我试图展示如何思考。

    请注意,对于不同的上下文,您确实不需要完整的对象,只需要它的“短”形式,这通常意味着引用(如在 Id 中)。但从上下文的角度来看,该引用代表了一个概念。请注意,实体或引用不是出于导航目的。它们在那里是因为它们有助于定义域概念。

    此外,定义一个具有单一目的的业务对象作为其他人的容器是没有意义的。在领域建模中,关系应该被视为定义。

    您应该熟悉 CQRS(将写入与读取分开)。这将使保存/恢复业务模型变得微不足道,同时让您对查询感到疯狂。而且您将不需要 ORM。

    底线,您应该根据您正在工作的层(关注点)对事物进行建模。然后使用映射器将相关模型从一层/上下文“转换”到另一层/上下文。不要试图创建适合所有目的的终极模型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多