PHP DataMapper具有多个持久层

时间:2012-10-25 08:07:10

标签: php oop architecture datamapper

我正在用PHP编写一个必须写入三个持久层的系统:

  • 一项网络服务
  • 两个数据库(一个mysql一个mssql)

原因是遗留系统无法更改。

我想使用DataMapper模式,我正在尝试建立实现我想要的最佳方式。我有一个如下界面:

<?php
    $service = $factory->getService()->create($entity);
?>

为简洁起见,下面是一些人为设计的代码:

<?php
class Post extends AbstractService
{
    protected $_mapper;

    public function create(Entity $post)
    {
        return $this->_mapper->create($post);
    }
}

class AbstractMapper
{
    protected $_persistence;

    public function create(Entity $entity)
    {
        $data = $this->_prepareForPersistence($entity);
        return $this->_persistence->create($data);
    }   
}
?>

我的问题是,因为有三个持久层,因此每个都可能需要三个映射器。我想要一个干净的设计模式灵感的界面,使这项工作。

我认为它有三个选项:

  1. 将三个映射器注入服务并在每个
  2. 上调用create
  3. $ _ mapper是一个数组/集合,它遍历它们,在每个
  4. 上调用create
  5. $ _ mapper实际上是一个充当a的容器对象 每个
  6. 进一步代理和调用创建

    对于这些解决方案中的每一个解决方案都是错误的,并且会感谢任何可能适合的反馈/认可设计模式。

3 个答案:

答案 0 :(得分:2)

我必须解决类似的问题,但很多年前在PEAR DB时代。在这种特殊情况下,需要跨多个数据库复制数据。

我们没有不同数据库具有不同映射的问题,所以它更简单一点。

我们所做的是对DB类进行外观并覆盖getResult函数(或者它所调用的任何函数)。然后,这个函数分析了SQL,如果它是一个读取 - 它会将它发送给一个支持的,如果它是一个写,它会将它发送给所有人。

这对于利用率很高的网站来说确实很有效。

在此背景下,我建议完全介绍所有持久性操作。完成后,实现细节不太相关,可以随时更改。

从这个角度来看,您的任何实施想法似乎都是一种合理的方法。但是你会想到各种各样的事情。

  • 如果其中一个后端出错,该怎么办?
  • 写入三台数据库服务器会对性能产生什么影响?
  • 写入是否可以异步完成(如果是,请再次询问第一个问题)

还有另一种方法可以解决这个问题。那就是使用存储过程。如果您有主数据库服务器,则可以编写一个触发器,在提交(或其附近)连接到另一个数据库并同步数据时。

如果数据更新不需要立即进行,您可以让主数据库记录更改,并使另一个脚本定期将这些数据“提供”到另一个系统中。同样,需要考虑错误问题。

希望这有帮助。

答案 1 :(得分:1)

首先,一些术语:你称之为三层,实际上是三个模块,而不是层。也就是说,持久层中有三个模块。

现在,这个问题的基本前提是:你必须有三种不同的持久性逻辑,对应三种不同的存储源。这是你无法避免的事情。因此,问题只是关于如何在这个模块上调用写操作(假设对于读取你不需要调用所有三个,或者如果你这样做,那么这是一个单独的问题)。

从您列出的三个选项中,我认为第一个选项更好。因为,这是三者中最简单的一个。另外两个,仍需要分别调用三个模块,另外还有引入容器或某种数据结构的工作。你仍然无法避免在某处调用三个模块。

如果使用第一个选项,那么您显然需要使用接口,为用户/客户端(在本例中为服务)提供统一的抽象。

我的观点是: 它们是你问题的固有复杂性,你不能进一步简化。 2.第一种选择更好,因为另外两种选择,使事情变得更复杂,而不是简单。

答案 2 :(得分:0)

我认为选项#2在我看来是最好的。我会那样做的。如果你有10+映射器而不是选项#3将创建逻辑转移到映射器本身是有意义的,但由于你有合理数量的映射器,因此只需注入它们并迭代它们就更有意义了。通过添加另一个映射器来扩展功能只需要在依赖注入配置中添加一行。