DDD和MVC:'模型'和'实体'之间的区别

Nat*_*ing 53 php model-view-controller entity domain-driven-design model

我对MVC中"模型"的概念感到非常困惑.今天存在的大多数框架将模型放在Controller和数据库之间,而模型几乎就像数据库抽象层.随着Controller开始做越来越多的逻辑,'Fat Model Skinny Controller'的概念就丢失了.

在DDD中,还有域实体的概念,它具有唯一的身份.据我了解,用户是实体的一个很好的例子(例如,唯一的用户ID).实体有一个生命周期 - 它的值可以在整个动作过程中改变 - 然后它被保存或丢弃.

我上面描述的实体是我认为模型应该在MVC中的内容?我有多偏离基础?

为了使事情更加混乱,你会引入其他模式,例如Repository模式(可能会在其中放置一个Service).很清楚Repository如何与实体交互 - 它与模型有什么关系?

控制器可以有多个模型,这使得模型看起来像一个"数据库表"而不是一个独特的实体.

更新: 在这篇文章中,模型被描述为具有知识的东西,它可以是单数或对象的集合.所以听起来更像是一个实体,一个模型或多或少都是一样的.模型是一个包罗万象的术语,其中实体更具体.值对象也是一个模型.至少在MVC方面.也许???

所以,从非常粗略的角度来看,哪个更好?

没有"模特"真的......

class MyController {
    public function index() {
        $repo = new PostRepository();
        $posts = $repo->findAllByDateRange('within 30 days');
        foreach($posts as $post) {
            echo $post->Author;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者这个,它有一个模型作为DAO?

class MyController {
    public function index() {
        $model = new PostModel();
        // maybe this returns a PostRepository?
        $posts = $model->findAllByDateRange('within 30 days');
        while($posts->getNext()) {
            echo $posts->Post->Author;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这两个例子都没有做我上面描述的内容.我很丢失.有什么输入?

Ven*_*emo 47

实体

Entity表示一个对象,它是业务逻辑使用的单个项目,更具体地说是具有某种身份的对象.
因此,许多人将ORM映射对象称为实体.

有些将" 实体 "称为类,其实例表示数据库中的单个行.

其他一些人更喜欢只将这些类中的那些称为"实体",它们也包含业务规则,验证和一般行为,并且将其他类称为" 数据传输对象 ".

模型

A Model与应用程序的UI(= View)和控制流(= Controller)没有直接关系,而是与数据访问和应用程序的主数据抽象的工作方式有关.

基本上,任何东西都可以成为符合上述要求的模型.

MVC

您可以在MVC中使用实体作为模型.它们意味着两种不同的东西,但同一类可以同时被称为.

例子

  • Customer类是非常多的实体(通常情况下),你也可以使用它作为您的应用中的数据访问的一部分.在这种情况下,它既是实体又是模型.
  • Repository类可以是模型的一部分,但它显然不是一个实体.
  • 如果您在业务逻辑层的中间使用了一个类,但没有暴露给应用程序的其余部分,那么它可能是一个实体,但从MVC应用程序的角度来看,它显然不是一个模型.

你的榜样

至于你的代码示例,我更喜欢第一个.
Model是一个类,用作应用程序的数据抽象方式,而不是名称后缀为"Model"的类.很多人都认为后者是英国媒体报道.

您几乎可以将Repository类视为模型的一部分,即使其名称没有以"Model"为后缀.

我想补充的是,使用第一个更容易,而对于后来可能需要了解您的代码的其他人,它更容易理解.

  • 该模型是一个**层**。例如,没有“用户模型”这样的东西。 (2认同)

小智 12

所有答案都是不同事物的混搭,简直就是错误.

DDD中的模型很像现实世界中的模型:事物的简化和抽象.不少也不多.它与数据,对象或其他任何东西无关.它只是域部分的概念.在每个复杂的领域,总有不止一种模式,例如交易,发票,物流.

实体不是"具有身份的模型",而只是具有身份的对象.

存储库不仅是一级缓存,也是域的一部分.它给出了内存中对象的错觉,并负责从任何地方获取聚合(而不是实体!)并保存它们,即维护对象的生命周期.

如果你谈论DDD概念,首先要通过阅读基础知识来修复你的知识.就像在这里ThinkDDD.

  • 你的最后一句话没有理由苛刻:我要求澄清这一点.我已经阅读了基础知识,但没有找到任何帮助,所以我问道.你的答案与erenon的答案基本相同; 模型是域中某事物的表示.模型是对象,但并非所有对象都是模型.正方形是一个矩形...... (5认同)
  • 答案是好的,但我同意内森 - 请尽量保持文明,严厉劝阻. (3认同)

Ken*_*thJ 6

应用程序中的"模型"是保存数据的位.如果我没记错的话,域驱动设计中的"实体"是具有身份的模型.也就是说,实体是通常直接对应于数据库或文件中的"物理"元素的模型.我相信DDD定义了两种类型的模型,一种是实体,另一种是价值,它只是一种没有和身份的模型.

存储库模式只是一种索引的模型/实体集合.因此,例如,如果您的代码需要订单#13,它将首先向存储库询问它,如果它无法从那里获取它,它将从任何地方获取它.如果你愿意,它基本上是一级缓存.它与模型的作用方式以及它如何与实体一起行动没有区别,但由于存储库的想法是能够使用其ID来获取模型,因此就DDD而言,只允许实体进入库.