Doctrine 2和Propel 1.6的弱点和力量

时间:2012-08-19 11:10:39

标签: php doctrine-orm propel

我想知道Doctrine 2和Propel 1.6的优点和缺点是什么。 例如,Doctrine 2实际上是用户友好的,但如果你想要超越顺从,就会限制你。 Doctrine 2文档缺乏更新......

如果可能的话,您可以分享您在Doctrine2表现良好或Propel完美的地方的经验。

提前致谢。

1 个答案:

答案 0 :(得分:18)

<强> EDITED

我只是joined the chat就此问题获得了一些见解。我们来一个简历:

Single Responsibility Principle

  • 只有Doctrine 2.x使用了一些DataMapper的想法
  • 开发人员仍然认为 ActiveRecord 是众神的狂野
  • 无法与DB分开测试
  • 依赖注入敌人

请参阅:https://softwareengineering.stackexchange.com/questions/119352/does-the-activerecord-pattern-follow-encourage-the-solid-design-principles

<强>描述

Propel基于ActiveRecord模式和Doctrine,而是使用Data MappersVirtual Proxies

当我第一次学习使用PHP的OOP时,ActiveRecord被广泛使用,大部分是由于Ruby On Rails的影响。然后开发人员开始意识到ActiveRecord是一个有限的概念,特别适用于大型应用程序。

为什么?

自己思考一下,域模型对象有责任知道如何自救吗?或者甚至将其数据转换为JSON格式?

答案是否定的,因为它违反了Single Responsibility Principle (SRP)和域cohesion

  

Martin将责任定义为改变的理由,并得出结论   一个类或模块应该只有一个,而且只有一个可以改变。

假设您有一个Author实体。你有什么理由改变它? 好吧,如果使用ActiveRecord实现,除了需要更改对象属性本身之外,如果实现特定于该对象的新类型持久性,则还需要更改它,就像我们在实现缓存策略时那样。

另外,假设Propel库改变了模型基类的方法(只是一个简单的例子)。现在您有理由更改应用程序中没有任何持久性的部分,因为您的实体与ORM基类紧密结合。换句话说,您的域模型对象不应该依赖于每个ORM框架的细节。您应该能够更改ORM,让您的域模型对象不受影响。

因此,活动记录要求您的域模型了解持久层的存在。 两个职责

使用Active Record时最糟糕的事情就是你“搞砸”你的域模型继承层次结构。如果为了持久性目的而扩展基类的Human实体,然后扩展Man实体的Human实体,如果由于某种原因,您有另一个Woman实体扩展如果Human实体无法持久化,那么您将打破基类建立的contract,该基类声明每个实体都需要知道如何保存自己。你将无法$woman->save()

严格地说,它也会导致违反Liskov Substitution Principle

最后,停止使用ActiveRecord 的最终原因。查看以下代码,您将能够看到ORM在事务期间将对象映射到存储的责任委托给域模型实体:

class Book extends BaseBook
{
  public function postSave(PropelPDO $con)
  {
    $this->updateNbBooks($con);
  }

  public function postDelete(PropelPDO $con)
  {
    $this->updateNbBooks($con);
  }

  public function updateNbBooks(PropelPDO $con)
  {
    $author = $this->getAuthor();
    $nbBooks = $author->countBooks($con);
    $author->setNbBooks($nbBooks);
    $author->save($con);
  }
}
  

http://www.propelorm.org/documentation/06-transactions.html你必须   每次保存或删除Book对象时都更新此新列;   这会使写查询慢一点,但读取查询的次数更多   快点。幸运的是,Propel模型对象支持前后挂钩   对于save()和delete()方法,所以这很容易   实施

因此,在单个模型实体中,您有:

  1. 持久性
  2. 拦截过滤器模式以进行保存/删除之前和之后
  3. 验证(http://www.propelorm.org/documentation/05-validators.html
  4. 高速缓存
  5. 你去了......