Подтвердить что ты не робот

Слабые стороны и силы доктрины 2 и Propel 1.6

Я хотел бы знать, каковы силы и недостатки Doctrine 2 и Propel 1.6. Например, Doctrine 2 действительно удобна для пользователя, но ограничивает вас, если вы хотите выйти за рамки конформизма. Документация Doctrine 2 отсутствовала...

Если возможно, вы можете поделиться своим опытом с тем, где Doctrine2 работает хорошо или где Propel был идеальным.

Спасибо заранее.

4b9b3361

Ответ 1

EDITED

Я только присоединился к чату, чтобы получить некоторые сведения по этому вопросу. Позвольте сделать резюме:

Single Responsibility Principle

  • только Doctrine 2.x использует некоторые идеи DataMapper
  • Разработчики по-прежнему считают, что ActiveRecord - это амброзия от богов
  • Неспособность тестировать отдельно от DB
  • Врач-зависимый враг

Смотрите: https://softwareengineering.stackexchange.com/info/119352/does-the-activerecord-pattern-follow-encourage-the-solid-design-principles

Описание

Propel основан на ActiveRecord Pattern и Doctrine, вместо этого используйте Data Mappers и Виртуальные прокси.

Когда я впервые узнал о OOP с PHP, ActiveRecord широко использовался, в основном из-за влияния Ruby On Rails. Затем разработчики начали понимать, что ActiveRecord - это ограниченная концепция, специально для более крупных приложений.

Почему?

Подумайте сами, лежит ли объект предметной области домена, чтобы знать, как сохранить себя? Или даже преобразовать свои данные в формат JSON?

Ответ отрицательный, поскольку он нарушает принцип единой ответственности (SRP) и домен cohesion.

Мартин определяет ответственность как причину изменения и заключает что класс или модуль должны иметь одну и только одну причину для изменения.

Скажем, у вас есть объект Author. По каким причинам вы его измените? Ну, если он реализован с использованием ActiveRecord, помимо необходимости изменять свойства объекта, вам также потребуется изменить его, если вы реализуете новый тип персистенции, характерный для этого объекта, как и при реализации стратегий кэширования.

Кроме того, скажем, библиотека Propel меняет метод базового класса модели (просто наивный пример). Теперь у вас есть причина изменить другие части вашего приложения, которые не имеют ничего с сохранением, поскольку ваши сущности тесно связаны с базовым классом ORM. Другими словами, объекты вашей модели домена не должны зависеть от особенностей каждой ORM Framework. Вы должны иметь возможность изменить ORM, позволяя объектам модели домена оставаться нетронутыми.

Поэтому для активной записи требуется, чтобы ваша модель домена знала о существовании слоя сохранения. Есть две обязанности.

Самое плохое при использовании Active Record - это то, что вы "испортили" свою иерархию наследования модели домена. Если у вас есть объект Human, расширяющий базовый класс для целей сохранения, а затем объект Man, расширяющий объект Human, если по какой-то причине у вас есть другой объект Woman, расширяющий объект Human без возможности чтобы быть сохраненным, тогда вы нарушите contract, установленный базовым классом, в котором говорится, что каждый объект должен знать, как сохранить себя. Вы не сможете сделать $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 Вы должны обновлять этот новый столбец каждый раз при сохранении или удалении объекта книги; это сделает запросы записи немного медленнее, но много читает запросы Быстрее. К счастью, объекты модели Propel поддерживают до и после крючков для методов save() и delete(), поэтому это довольно просто реализовать

Итак, в одном объекте модели у вас есть:

  • Постоянство
  • Перехват шаблона фильтра для предварительного и последующего сохранения/удаления
  • Валидация (http://www.propelorm.org/documentation/05-validators.html)
  • Кэш
  • И там вы идете...