我想知道 Doctrine 2 和 Propel 1.6 的力量和弱点是什么。例如,Doctrine 2 确实是用户友好的,但如果您想超越墨守成规,则会限制您。教义 2 文档缺乏更新...
如果可能的话,您可以分享 Doctrine2 在哪些方面做得很好或 Propel 在哪些方面是完美的经验。
提前致谢。
我想知道 Doctrine 2 和 Propel 1.6 的力量和弱点是什么。例如,Doctrine 2 确实是用户友好的,但如果您想超越墨守成规,则会限制您。教义 2 文档缺乏更新...
如果可能的话,您可以分享 Doctrine2 在哪些方面做得很好或 Propel 在哪些方面是完美的经验。
提前致谢。
已编辑
我刚刚加入聊天以了解有关此问题的一些见解。让我们做一份简历:
描述
Propel 基于ActiveRecord模式,而 Doctrine 则使用数据映射器和虚拟代理。
当我第一次使用 PHP 了解 OOP 时,ActiveRecord 被广泛使用,这主要是由于 Ruby On Rails 的影响。然后开发人员开始意识到 ActiveRecord 是一个有限的概念,特别是对于大型应用程序。
为什么?
自己想想,是不是域模型对象有责任知道如何自救?甚至将其数据转换为 JSON 格式?
答案是否定的,因为它违反了单一职责原则 (SRP)和域凝聚力。
Martin 将责任定义为改变的理由,并得出结论认为一个类或模块应该有一个,而且只有一个改变的理由。
假设您有一个Author
实体。你会因为什么原因改变它?好吧,如果使用 ActiveRecord 实现,除了需要更改对象属性本身之外,如果您实现特定于该对象的新类型的持久性,您还需要更改它,就像我们在实现缓存策略时所做的那样。
另外,假设 Propel 库改变了模型基类的方法(只是一个简单的例子)。现在您有理由更改应用程序的其他部分,因为您的实体与 ORM 基类紧密耦合。换句话说,你的领域模型对象不应该依赖于每个 ORM 框架的细节。您应该能够更改您的 ORM,让您的域模型对象保持不变。
所以活动记录需要你的领域模型知道持久层的存在。有两个责任。
使用 Active Record 时最糟糕的事情是你“搞砸”了你的域模型继承层次结构。如果你有一个Human
实体为了持久化目的而扩展了一个基类,然后一个Man
实体扩展了该Human
实体,如果由于某种原因你有另一个Woman
实体扩展了该Human
实体而没有持久化的能力,那么你将打破基类建立的契约这表明每个实体都需要知道如何自救。你将无法做到$woman->save()
。
最后,停止使用 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() 方法的前钩子和后钩子,所以这很容易实现
因此,在单个模型实体中,您拥有: