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

时间:2010-06-12 20:12:22

标签: php model-view-controller model domain-driven-design entity

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

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

我上面描述的实体是我认为Model应该在MVC中的内容?我的基础怎么样?

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

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

更新: In this post模型被描述为具有知识的东西,它可以是单数或对象集合。所以听起来更像是一个实体,一个模型或多或少都是一样的。模型是一个包罗万象的术语,其中实体更具体。值对象也是一个模型。至少在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;
        }
    }
}

这些例子甚至都没有我上面描述的内容。我很丢失。有什么输入吗?

5 个答案:

答案 0 :(得分:45)

实体

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

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

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

模型

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

基本上,任何东西都可以是符合上述要求的模型。

MVC

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

<强>实施例

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

您的示例

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

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

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

答案 1 :(得分:10)

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

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

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

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

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

答案 2 :(得分:6)

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

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

答案 3 :(得分:1)

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

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

修改 模型(类)是实体方案的简单表示。模型(对象)是单个实体。该服务在模型上运行,并向控制器提供具体数据 s 。没有控制器有任何型号。模特独立。
在另一个“侧面”,映射器将模型映射到持久层(例如:数据库,第三方后端等)。

答案 4 :(得分:1)

虽然这是关于Ruby on Rails的,但由于围绕MVC和DDD的讨论,相同的原则和信息仍然适用。

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