了解域对象+数据映射器模式?

2024-02-23

我过去一直使用各种 ORM,并将所有逻辑放在模型中,无论其性质如何 - SQL、MongoDB 查询,甚至获取远程 JSON 对象。 但是,当需要确保松散耦合以实现高水平的可测试性时,这种方法的问题很快就会出现。

今天我读到了有关将模型分为两部分的内容,Domain objects & Data mappers.
如果我完全理解的话Domain objects完全不知道所使用的存储,而是为了处理业务逻辑而存在。Data mappers另一方面负责将数据集存储在Domain objects到一组数据存储。

然而,我确实发现在网上找到一个关于如何在现实世界示例中使用 DomainObjects 和 DataMappers 的良好且易于理解的示例有点困难。

这(下面显示的代码)是否是在我的代码中使用 DomainObjects 和 DataMappers 来存储用户的适当方法,还是我脑子里全错了?

$user = new User_DO;
$userSave = new User_DM;
$userSave->store( $user->add(array('name' => 'John Doe')) );

class User_DO {

    function add($array) {
        if(!isset($array['name'])) {
            throw new Exception("Name must be set");
        }

        return $array;

    }

}

class User_DM {

    function store($array) {
        MyDatabase::execute("INSERT INTO...");
    }

}

这背后的想法是有一个标准对象,它代表当前状态现实生活或者换句话说,在域中。这领域模型通常是没有逻辑的数据集合。

class person_DO {
    public $id;
    public $firstname;
    public $lastname;
    public $addresses;
}

该域模型实例的加载(领域对象)并且持久性是通过处理的数据映射器- 例如上述人员的地址可能通过 1:n 关系位于另一个表中,如下所示:

TABLE person {
    id        INTEGER PRIMARY KEY,
    firstname VARCHAR(32),
    lastname  VARCHAR(32)
}

TABLE addresses {
    id INTEGER PRIMARY KEY,
    person_id  INTEGER FOREIGN KEY ON person.id, --Reference on person-row
    street     VARCHAR(64),
    ...
}

person_DO 不需要知道这一点,但 datamapper 需要知道,因为它必须在加载期间聚合数据并在持久化期间分离:

class person_DM {
    /**
     * @param  [integer] $id
     * @return [person_DO] an instance of a person or null, if no person
     *                     with that id was found.
     */
    public function findById ($id) {...}

    /**
     * @return [array of person_DO]
     */
    public function fetchAll() {...}

    /**
     * persists a person object
     * @param [person_DO] an instance of a person
     */
    public function saveOrUpdate(person_DO $person) {...}
}

为了进一步解耦不同部分,DataMappers 通常使用数据库表网关或类似的模式以允许使用不同的数据库或类似的操作。这样,我可以拥有多个具有相同模式的数据库,但是例如在不同的组织中用相同的代码构建数据仓库,只是数据库对象不同。

作为一个实际的例子,我建议看看快速入门教程 http://framework.zend.com/manual/1.12/en/learning.quickstart.htmlZend Framework 的功能,它的作用正是我刚才简要解释的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解域对象+数据映射器模式? 的相关文章

随机推荐

  • C# 和 JavaScript 之间的时间跨度差异说明

    这是基于在 C 中计算 1970 年以来的毫秒数会产生与 JavaScript 不同的日期 https stackoverflow com q 22081128 1346943 and Javascript Date getTime 的 C
  • 简单游戏的 Canvas 与 SVG

    如果我想构建一个简单的游戏 贪吃蛇 西洋跳棋 吃豆人或其他游戏 什么是更好的方法 SVG 还是 Canvas 我感兴趣的事情 易于实施 Canvas 与 SVG 的学习曲线 例如 如果 SVG 的教程和社区支持明显减少 这对我来说至关重要
  • 从 jQuery 加载 symfony 2 目录中的 php 文件

    我在捆绑包内的树枝文件中有这行代码 jQuery BundleDir Bundle views mapname index html twig datacount load getDataCount php 我的问题是我需要将 getDat
  • 如何使用 jquery 操作查询字符串

    我有一个选择下拉列表 其中 id 映射到值 在 onChange 事件中 我想重定向到相同的 url 但将 id value 附加到查询字符串 如何检查此 id 选项是否已存在于查询字符串中 我不需要多个值 并根据需要替换 附加 我如何检查
  • 使用带有用户名和密码的 http 进行 Git 克隆

    我尝试使用 git 克隆http 用户 电子邮件受保护 http user password host com但我在添加用户或密码时遇到一些问题 因为用户使用的电子邮件包含其他 而密码使用感叹号 该命令看起来像http 电子邮件受保护 电子
  • PharData extractTo方法在linux环境下提取.tar.gz失败

    我想将 tar gz 文件提取到特定文件夹中 我使用 cURL 从 MailChimp 批量操作下载 tar gz 文件 我使用下面的代码来提取 tar 文件 phar new PharData upload test tar gz pha
  • 如果调用者返回太早,则异步 AWS Lambda 不会执行

    我正在尝试调用异步 lambda 函数within另一个 lambda 函数 我发现如果调用函数退出得太快 它就不会被执行 换句话说 以下内容永远不会起作用 LambdaFunction2 永远不会被调用 function lambdaFu
  • 在 OpenCV 中更新 Mat 的子矩阵

    我正在使用 OpenCV 和 C 我有一个像这样的矩阵 X Mat X Mat zeros 13 6 CV 32FC1 我只想更新它的一个 4x3 子矩阵 但我对如何有效地访问该矩阵存有疑问 Mat mat43 Mat eye 4 3 CV
  • 恢复备份mysql

    我在 mysql 中有一个 250MB 的数据库备份 如何将其恢复到另一台服务器上的新数据库中 或者只是使用php我的管理员为了恢复海豚
  • 分组数据框中日期范围重叠

    我如何知道两行的日期范围是否重叠 输入数据框 A B Start End Timestamp A1 B1 2022 01 15 2022 02 15 2021 05 17 A1 B1 2021 07 15 2021 10 17 2021 0
  • 在 Excel 中设置文本字符串列表的格式

    我正在尝试将 Excel 中出现的单词列表的字体变成红色 到目前为止 我能够找到一个单词 但我需要搜索整个数组 我是 VBA 新手 正在苦苦挣扎 到目前为止 我已经找到了一个解决方案 但它涉及查找单个字符串 F1 Sub test4Stri
  • 获取隐藏元素的偏移量

    如何获取隐藏元素的坐标 offset 不支持使用隐藏元素 有什么提示吗 如果你的元素有 hide 调用它 或者如果它有display none在CSS中 浏览器根本不费心去渲染它 在这种情况下 答案不是直接的 在最近的jQueries中 你
  • 在 Parse.com Cloud 代码 beforeSave 函数中访问原始字段

    最终目标是使用以下方法检测现有 Parse 对象和传入更新之间的更改beforeSave云代码中的函数 从 parse com 提供的 Cloud Code 日志中 我们可以看到以下内容的输入 beforeSave包含一个名为origina
  • cudart_static - 什么时候有必要?

    由于较新的驱动程序附带 CUDA 运行时 我可以在驱动程序下载页面中选择 9 1 或 9 2 我的问题是 我的库 内部使用 CUDA 内核 是否应该附带 lcudart static 我在使用 9 1 CUDA 驱动程序的系统上启动使用 9
  • 如何更改 catalina.out 的路径?

    我无法找到移动的设置catalina out记录到 var log jira 我成功设置了以下文件的路径access log log catalina log host manager log localhost log and manag
  • Python中是否可以动态生成命令Click

    我正在尝试生成click来自配置文件的命令 本质上 这个模式 import click click group def main pass commands foo bar baz for c in commands def f print
  • 使用正确的权限在 ASP.NET/C# 中启动服务

    在我的网站 用 ASP NET C 编写 上 我希望管理员能够启动某个服务 我为此的代码是 ServiceController svcController new ServiceController InvidualFileConversi
  • 什么时候可以不正常化? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何更改 c3 饼图中图例的文本

    如何更改饼图图例的文本 我在我的 php 页面中使用 c3 图表 我已经阅读了 c3 图表的文档 但没有运气 目前我正在使用这段代码 它显示图例true但我无法更改我尝试过的文本 var chart c3 generate bindto c
  • 了解域对象+数据映射器模式?

    我过去一直使用各种 ORM 并将所有逻辑放在模型中 无论其性质如何 SQL MongoDB 查询 甚至获取远程 JSON 对象 但是 当需要确保松散耦合以实现高水平的可测试性时 这种方法的问题很快就会出现 今天我读到了有关将模型分为两部分的