当我昨天问一个关于单数/复数模型命名约定的问题时,我遇到了域模型的概念.据我所知,到目前为止,域模型只是一个对象,它代表了我的应用程序中的一个实体.
要使用一个非常简单的示例,请执行以下操作:
class User {
private $name;
public setName() {}
public getName() {}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想到了这个问题,我如何从一些输入源,从数据库或数据源填充这个"域模型"?
在阅读关于域模型的过程中,我得到的印象是,在它们内部应该只有一个表示域概念的表示.所以现在我还需要另一个负责与数据源交互的类(DAO?),在这种情况下是一个名为"User"的数据库表.我的DAO类将处理插入,更新,删除和多次提取.
我想出了这种方法从输入填充用户域模型,在这种情况下发布数据,然后使用UserDAO类将记录保存到数据库:
/**
* Populating Domain Model from input, and saving to database
*/
/** Instantiate User Domain Model, and populate it from input */
$user = new User();
$user->setName($_POST['name']);
/** Creating a new database record from User Domain Model */
$userdao = new UserDAO($pdo);
$userdao->insert($user);
Run Code Online (Sandbox Code Playgroud)
这是我在需要获取数据时预期与数据库交互的方式,在这种情况下是多个用户记录:
/**
* Fetching data from database to populate User Domain Models in an array
*/
/** Instantiate new UserDAO object to interact with User table */
$users = new UserDAO($pdo);
$users->findAll();
$user_collection = [];
/** Loop UserDAO object set to populate user collection array */
foreach ($users as $user) {
/** Create new User domain object from row, and add to collection array */
$user = new User($user);
$user_collection[$user->name()] = $user;
}
Run Code Online (Sandbox Code Playgroud)
这似乎唯一真正的好处是组织.
我当前的迭代本质上有一个User类,它承担上面UserDAO类的所有职责,并直接从数据库中返回数据数组,然后我在"控制器"/"演示者"中使用它们,然后流入我的(被动)观点.
我想知道的是:
我是在正确的轨道上吗?
输入验证属于哪里?我认为它必须进入域模型,如果我的假设到目前为止是正确的?
除了帮助组织应用程序依赖和操作的基本概念之外,使用此技术有什么好处?为什么我需要这个额外的层而不是直接操作数据库的数组结果?
Agm*_*her 25
这里的关键是查看哪些类应该具有哪些职责,具体而言,需要哪些职责才能使您的域运行.
用户域对象
应负责关于告诉你关于它的状态到应用程序的有效业务规则(isAdmin(),isBanned(),isSuspended(),getWarnLevel()).将此对象视为API存储桶.你想知道什么?它可以告诉什么有用的信息?构建一个能够回答这些问题的API.小心不要让用户过多地告诉您系统中的其他对象.这不应该是它的责任.
关心:
不关心
用户存储库
一个类,负责允许您检索并保持完整形成的现有Users.也许它们在当前请求期间仅存储在内存中.也许他们坚持缓存.也许他们坚持使用MySQL.没关系.所有这一切都可以让你获得用户并坚持下去.这是它的责任.它可以但不必知道持久性机制.它只需要知道如何使用持久性机制.
(findById($id),findByEmail($email),findBanned(),findByCriteria($Criteria)-好候选人战略或规范模式,save($User),delete($User)).同样,这里的关键是构建一个满足域业务规则的API.您是否需要通过电子邮件地址查找用户?然后在存储库中创建一个显式访问点.如果你没有需要,那就不要了.你怎么需要找到Users?用API回答这个问题.
关心
不关心
User对象如何保持不变User对象用户工厂
UserRepositories用于处理现有User对象,但是如何在第一时间创建它们?有工厂.这些可以是简单的工厂,只需要一种类型的用户.或者它们可以是抽象工厂,可以生成不同类型的用户.这取决于您和您的系统需求.再次,认为什么是需要的API来满足您的域名空间的业务规则方面:( ,make($type, $data),).makeAdmin($data) makeMember($data)PHP 5.6的可变参数运算符语法将使这个WAY清理器与btw一起工作.
关心
Users不关心
UsersUser后做了什么用户网关/映射器
这可能是您的实际持久性机制:它可能直接与关系数据库接口,使用Factory,并被存储库使用.它执行实际的DB提取,并将数据映射到Factory可以消化的格式.工厂不应对此映射负责,因为它不应该知道源格式,只知道组装域对象所需的格式.因此,映射责任在于Gateway/Mapper.
关心
User获取/检索,以及如何不关心
User对象现在,不可否认,这看起来比实际更简单.你如何处理聚合的孩子(例如Comments属于一个的孩子Post)?你在什么阶段给那些人Post?你是否一直给他们,或者只有当你明确要求它时(例如通过回调?)这些是我没有答案的棘手问题,并且部分由你的领域需求来回答第一名.
ORM是一个难以解决的问题.主义和雄辩是优秀的,但不严格遵循上述模式.那没关系.上面的模式是一个指导原则,而不是规则.它的目标是专注于关注点分离和重点责任.您的应用程序可能没有必要拥有所有这些层.
关于验证,有两种验证:
表单输入验证
域对象验证
表单验证通常最好通过表单验证器类和为给定表单专门定义的一些规则来完成.通常,您可以在任何表单构建器类中定义这些规则(例如Form::text('first_name', array('rules' => 'required|alpha'))).控制器应该将表单验证器作为依赖项,但不应该自己进行实际验证.
域对象程序集验证(例如,保护模型的完整性)可以通过setter在域对象本身中存在,也可以在工厂中存在.这完全取决于您计划构建域对象的方式.
应该注意的是,您应该具有两种类型的验证:表单验证以验证输入,以及域对象验证以在创建对象时验证数据完整性.
| 归档时间: |
|
| 查看次数: |
4244 次 |
| 最近记录: |