【问题标题】:How to extend this simple DataMapper?如何扩展这个简单的 DataMapper?
【发布时间】:2010-09-21 10:25:00
【问题描述】:

有人可以从以下内容中得出一个具体的例子吗:

http://www.urdalen.com/blog/?p=210

..这说明如何处理one-to-manymany-to-many 关系?

我前段时间给作者发了邮件,但没有收到回复。我喜欢他的想法,但除了简单的单表关系之外,我不知道如何实现它。

注意:我不想使用成熟的 ORM。我喜欢手工编写 SQL。不过,我想改进我的应用程序代码的设计。现在,每个域对象都有自己的类,其中充满了封装在静态方法中的查询。它们只是根据查询返回标量、一维数组(记录)或二维数组(记录集)。

【问题讨论】:

    标签: php design-patterns orm datamapper


    【解决方案1】:

    ORM(所谓的阻抗失配)的问题正是关系。在对象图中(内存中对象),关系是指向其他对象的指针。在关系数据库中,关系是颠倒的;这使得无法在两个模型之间进行简单的映射,这就是 ORM 如此复杂的原因。

    如果您想靠近数据库(避免使用 ORM),那么您不应该尝试抽象关系。我编写数据映射器的方式如下:

    $car42 = $car_gateway->fetch(42);
    $wheels = $wheel_gateway->selectByCar($car42);
    

    对比ORM方式:

    $car42 = $car_gateway->fetch(42);
    $wheels = $car42->selectWheels();
    

    这确实意味着网关最终出现在您的客户端代码中,但它也使事情变得非常透明并接近数据库。

    【讨论】:

      【解决方案2】:

      如果您正在寻找简单且可移植的 DataMapper ORM,请查看phpDataMapper。它仅依赖于 PHP5 和 PDO,而且它非常小巧轻便。它还支持表关系和其他一些非常好的功能。

      【讨论】:

        【解决方案3】:

        鉴于您对 Tom 的回答,我建议您查看 Zend Framework 之类的东西。它的 ORM 有一个接受或离开它的架构,可以分阶段实现。

        当我来到我现在的雇主那里时,他们有一份几个月前刚刚完成的申请,但已经通过了一两个之前的版本,而当前版本的开发时间比预期的要长六个月。但是,代码库很混乱。例如,数据库访问逻辑和业务逻辑之间没有抽象。而且,他们希望我推动网站向前发展,构建新功能、扩展现有功能并修复代码中的现有错误。更复杂的是,他们没有在数据输入或输出上使用任何形式的卫生设施。

        当我开始涉足这个问题时,我意识到我需要一个可以分步实施的抽象问题的解决方案,因为它们显然不会完全重写。我最初的方法是编写一个自定义的 ORM 和 DAL,这将为我完成繁重的工作。它工作得很好,因为它没有侵入现有的代码库,因此它允许我以不显眼的方式将应用程序的整个部分移动到新架构中。

        但是,在将我们网站的大部分用户区域移植到这个新结构并在我的自定义框架上构建了一个完整的应用程序(其中还包括一个自定义前端控制器和 mvc 实现)之后,我正在切换到 Zend 框架(这是我的选择,尽管我确信其他一些框架也可以在这种情况下工作)。

        在切换到 Zend 框架时,我完全不担心遗留代码库,因为:

        • 我可以构建新模型和重构 旧模型(建立在我的自定义 框架)不显眼。
        • 我可以重构现有的 控制器(例如它们)是 包装在一个行为的类中 以与 Zend 一致的方式 MVC 框架使其成为一个 实际开始使用的小问题 Zend 的前端控制器。
        • 我们的视图已经内置 Smarty 所以我不用担心 关于分离控制器和视图 逻辑,但我将能够扩展 Zend 框架,这样我就可以 在 Smarty 中渲染现有模板 在构建新模板时 直接 PHP。

        基本上,Zend Framework 有一个接受它或离开的架构,这使得在现有项目中使用它是一种乐趣,因为新代码和重构代码不需要侵入现有代码。

        【讨论】:

        • 感谢您的回答。我想我会根据 troelskn 的回答保留它们:“如果你想靠近数据库,那么你不应该尝试抽象关系。”我确实想靠近 DB,因为现有的查询运行良好。 (续)
        • 因此,我只想重构 PHP 而不是 SQL。我想我尝试了一个类似于 troelskn 建议的接口,除了我没有将结果封装在一个对象中之外,它几乎就是这样。
        • 请注意;在 PHP 中将实体封装在对象中似乎有点多余,但我发现它有助于使事情更清晰。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多