什么,*具体*,使DataMapper比ActiveRecord更灵活?

时间:2011-02-17 18:17:55

标签: php database orm datamapper

我正在比较Doctrine 2 and Propel 1.5/1.6,我正在研究他们使用的一些模式。 Doctrine使用DataMapper模式,而Propel使用ActiveRecord模式。虽然我可以看到DataMapper 相当更复杂,但我认为这种复杂性带来了一些设计灵活性。到目前为止,我发现使用DataMapper而不是ActiveRecord的唯一正当理由是DataMapper在单一责任原则方面更好 - 因为数据库行不是持久化的实际对象,但是Propel并不是真的关心我,因为无论如何它都是生成的代码。

那么 - 是什么让DataMapper变得更加灵活?

2 个答案:

答案 0 :(得分:4)

我和新的Propel和Doctrine2都合作过。 DataMapper(我的意思是Doctrine2)让你觉得很可爱的是你的域对象干净简单,它们不会扩展不相关的类,这会为你的类添加许多不相关的方法(正如你所说的那样违反了SRP)。它们只是简单的实体,具有一些属性和一些属于业务层的方法。当然,这可以让你为它们编写单元测试并在将来重用它们。

我不会说DataMapper要复杂得多。如果你编写自己的DataMapper实现,这很复杂,但Doctrine2比推进更容易使用(可能除了设置之外,我们只做一次)。它有一个操纵任何实体的实体管理器。您可能拥有复杂查询的实体存储库。就是这样。

实体就像:

一样简单
/**
 * Question
 *
 * @Entity
 */
class Question
{
    /**
     * @Column(type="string")
     */
    private $title;

    public function getTitle() { return $this->title; }
    public function setTitle($title) { $this->title = $title; }

}

在Propel中,我们将为该实体提供6个类,其中包含大量生成且通常未使用的代码。

是什么让DataMapper更灵活?它提供的简单性。

答案 1 :(得分:2)

ActiveRecord使数据类型做两件事 - 自己负责将数据保存到数据库,并负责存储数据以进行常规计算。这意味着如果您想要更改将来保留数据的数据存储,那么通常不必关心数据库行为的代码会受到更改。

DataMapper将给定的数据库实现与一组内存中的工作对象完全分离,这意味着可以将相同的内部工作数据类型保存到多个数据库,而无需修改否则使用工作类型的代码。

例如,对于DataMapper模式,如果明天要为数据添加XML导出,则需要实现一个新的数据映射器,即" MyDataToXmlDataMapper"或类似的,添加新的持久性格式,而不必更改其他代码。使用ActiveRecord添加此类功能需要更改工作数据类型的接口。