我对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;
}
}
}
这些例子甚至都没有我上面描述的内容。我很丢失。有什么输入吗?
答案 0 :(得分:45)
Entity
表示一个对象,它是业务逻辑使用的单个项目,更具体地说是那些具有某种身份的对象。
因此,许多人将ORM映射对象称为实体。
有些人将“ entity ”称为一个类,其实例表示数据库中的单个行。
其他一些人更喜欢只将这些类中的那些调用为“实体”,它还包含业务规则,验证和一般行为,并将其他类称为“数据传输对象”。 / p>
Model
与应用程序的UI(= View
)和控制流(= Controller
)没有直接关系,而是与数据访问的方式有关并且应用程序的主要数据抽象工作。
基本上,任何东西都可以是符合上述要求的模型。
您可以在MVC中使用实体作为模型。它们意味着两种不同的东西,但同一类可以同时被称为。
<强>实施例强>
Customer
类非常实体(通常),您还可以将其用作应用中数据访问的一部分。在这种情况下,它既是实体又是模型。Repository
类可能是模型的一部分,但它显然不是实体。您的示例
至于你的代码示例,我更喜欢第一个。
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