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

2010-06-13 php model-view-controller model domain-driven-design entity

我对MVC中“模型”的概念感到非常困惑。当今存在的大多数框架都将模型放置在Controller和数据库之间,并且该模型几乎像数据库抽象层一样工作。随着控制器开始执行越来越多的逻辑,“胖模型瘦控制器”的概念已消失。

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

我在上面描述的实体是我认为模型应该在MVC中使用的实体?我到底有多低调?

为了使事情更加混乱,您需要引入其他模式,例如存储库模式(也许在其中放置服务)。很明显,存储库将如何与实体交互-如何与模型交互?

控制器可以有多个模型,这使得模型似乎比唯一的实体少了一个“数据库表”。

更新: 在这篇文章中 ,模型被描述为具有知识的事物,它可以是单数或对象的集合。因此,听起来更像是实体和模型几乎相同。模型是一个笼统的术语,其中实体更具体。值对象也将是模型。至少就MVC而言。也许???

那么,以粗略的说法,哪个更好?

没有“模特”真的...

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

还是这个,有一个模型作为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;
        }
    }
}

这两个例子甚至都没有达到我上面所描述的。我显然迷路了。有输入吗?

Answers

使用服务和集合的简单解决方案:

<?php
class MyController {
    public function index() {
        $postService = ServiceContainer::get('Post');
        $postCollection = $postService->findAllByDateRange('within 30 days');
        while($postCollection->getNext()) {
            echo $postCollection->current()->getAuthor();
        }
    }
}

编辑: 模型(类)是实体方案的简单表示。模型(对象)是单个实体。此服务在模型运行,提供具体的数据,控制单元S。没有控制器具有任何模型。这些模型是独立的。
另一方面,映射器将模型映射到持久性层(例如:数据库,第三方后端等)。

实体

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

有些人将其称为“ 实体 ”,该类的实例表示数据库中的单行。

其他一些人更喜欢仅将这些类中的那些称为“实体”,其中还包含业务规则,验证和一般行为,而其他人则将其称为“ 数据传输对象 ”。

模型

Model是与应用程序的UI(= View )和控制流(= Controller )不直接相关的东西,而是与应用程序的数据访问和主要数据抽象方式有关的方式。

基本上,任何事物都可以是符合上述条件的模型。

MVC

您可以在MVC中将实体用作模型。它们意味着两个不同的事物,但是相同的类可以被称为两者。

例子

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

你的例子

至于您的代码示例,我希望使用第一个。
Model是用于作为应用程序的数据抽象手段的类,而不是名称后缀为“ Model”的类。许多人认为后者是过时的软件。

您几乎可以将您的Repository类视为模型的一部分,即使其名称不带“ Model”后缀。

我要补充一点的事实是,与第一个代码一起使用也更容易,而对于以后可能需要理解您的代码的其他人来说,也更容易理解。

尽管这是专门针对Ruby on Rails的,但由于讨论的是MVC和DDD,因此相同的原理和信息仍然适用。

http://blog.scottbellware.com/2010/06/no-domain-driven-design-in-rails.html

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

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

所有答案都是不同事物的沉重混搭,简直是错误的。

DDD中的模型非常类似于现实世界中的模型: 事物的简化和抽象。 不多也没有。 它与数据,对象或任何其他事物无关。 这只是领域部分的概念。而且在每个复杂领域 总有不止一种模式,例如交易,进销存,物流。

实体不是“具有身份的模型”,而仅仅是具有身份的对象。

存储库不仅是一级缓存,而且还是域的一部分。 它给人一种内存对象的错觉,并负责获取 从任何地方聚合(不是实体!)并保存它们 即保持对象的生命周期。

Related