【问题标题】:DDD and MVC: Difference between 'Model' and 'Entity'DDD 和 MVC:“模型”和“实体”之间的区别
【发布时间】:2011-03-03 01:52:43
【问题描述】:

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

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

我上面描述的实体是我认为模型应该在 MVC 中的吗?我离基地有多远?

为了让事情变得更加混乱,您可以使用其他模式,例如存储库模式(可能会在其中放置一个服务)。存储库如何与实体交互非常清楚——它如何与模型交互?

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

更新: 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;
        }
    }
}

这两个例子都没有达到我上面描述的效果。我显然迷路了。有什么意见吗?

【问题讨论】:

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


    【解决方案1】:

    实体

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

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

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

    型号

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

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

    MVC

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

    示例

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

    你的例子

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

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

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

    【讨论】:

    • 模型是一个。例如,没有“用户模型”之类的东西。
    • @Jimbo 如果模型是一个,我们可以进一步说应用模型和它的实体之间存在一对多的关系吗?例如,来自this answer“...模型是数据的表示,是封装应用程序中实体的类(以及扩展的对象)。”
    • 模型层包含实体和许多其他对象。 “MVC”在网络环境中不以经典形式存在,这让我感到困惑,因为他有很高的代表并且来自 Nerdery(我听说过的一群体面的程序员:-))。我们在 PHP 中没有 MVC,因此将其纳入讨论的前沿很重要。
    【解决方案2】:

    所有答案都是不同事物的大量混搭,完全是错误的。

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

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

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

    【讨论】:

    • 你的最后一句话没有理由苛刻:我只是要求澄清这一点。我已经阅读了基础知识,但没有找到任何帮助,所以我问了。您的回答本质上与erenon的回答相同;模型是域中事物的表示。模型是对象,但并非所有对象都是模型。正方形就是长方形...
    • 答案很好,但我同意内森的观点——请尽量保持文明,强烈反对严厉。
    • 链接 ThinkDDD 需要登录,反正我也没那么感兴趣,你的解释和其他解释一样正确/错误。你应该提供一些你的陈述的具体实现
    • SO 真的没有任何地方可以容纳那种“填充衬衫”的态度。请文明一点。
    • @Don Zampano :我同意你关于阅读基础知识的观点。你能给我一个完整的链接吗,我什么时候能得到可靠的信息? ;-)
    【解决方案3】:

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

    存储库模式只是模型/实体的一种索引集合。因此,例如,如果您的代码想要订单 #13,它会首先向存储库请求它,如果它无法从那里获取它,它会从任何地方获取它。如果您愿意,它基本上是一级缓存。它与模型的行为方式和实体的行为方式没有区别,但是由于存储库的想法是能够使用模型的 ID 获取模型,就 DDD 而言,只有实体才被允许进入存储库。

    【讨论】:

    • 对此持保留态度,我也在学习这种模式。但我开始怀疑“模型”一词是否将两个或三个相似但独立的概念混为一谈,尤其是在 Laravel 中。 1)如何与数据库表交互的抽象。 2) 表示其中单个记录的响应结构。 3)一个通用层,其中表示某种数据集的任何类都可以称为模型。所以要正确回答这个问题,我觉得你首先需要定义你的上下文。
    【解决方案4】:

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

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

    编辑: 模型(类)是实体方案的简单表示。模型(对象)是一个单一的实体。该服务对模型进行操作并向控制器s提供具体数据。没有控制器有任何型号。这些模型是独立的。
    另一方面,映射器将模型映射到持久层(例如:数据库、第 3 方后端等)。

    【讨论】:

    • 好的,只要在里面放一个工厂。但是其中的模型到底是什么?
    • 我想我要问的是:这些示例中的“模型”是包含“作者”变量的奇异 Post 对象吗?或者模型是更高层次的东西?
    【解决方案5】:

    虽然这里专门针对 Ruby on Rails,但由于讨论是围绕 MVC 和 DDD 进行的,所以相同的原则和信息仍然适用。

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

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 2013-03-10
      • 1970-01-01
      • 2017-06-10
      • 2017-01-16
      • 1970-01-01
      • 2015-10-01
      • 2012-06-28
      相关资源
      最近更新 更多