Doctrine ORMがPHPに悪い理由

この記事はLucas CorbeauxによるDoctrine ORMがPHPに適さない理由の翻訳です。



この記事のタイトルはトローリングに似ていることを知っています。 しかし、これはそうではなく、単なる事実の表明です。 私はDoctrineが悪いライブラリであるとか、使用すべきではないと言っているのではありません。 PHPには適していないと言っているだけです。この点を無視して誤って使用すると、深刻な問題が発生する可能性があります。



Hibernate ORMに触発されたDoctrine



2000年代に戻りましょう。 Javaは非常に人気があり、最もよく使用されるJavaライブラリの1つはORM Hibernateです。 独自のHQLクエリ言語がバンドルされており、Javaコミュニティに愛されていました。 Hibernateは、Javaオブジェクトとリレーショナルテーブルの共存を支援しました。



DoctrineはHibernateの概念に触発され、それらをPHPの世界に持ち込みたいと考えました。



JavaとPHPの違い



しかし、PHPはJavaではありません。このことから非常に重要な結論を導き出すことができます。 Javaアプリケーションは、PHPリクエストよりもずっと長く生きます。



ORMは、すべてのユーザー間のデータの整合性を考慮する必要があります。 時間の経過とともに、データベースの各変更はすべてのオブジェクトに反映されるはずです。 これが、ORMが非常に複雑な理由の1つです。



そして、それがORMパターンがPHPでほとんど必要ない理由です。 HTTPプロトコルはステートレスプロトコルであるため、すべての呼び出し間でデータの一貫性を維持する必要はありません。



セッションの問題



もちろん、これは真実ではないと言うことができます。 セッションを使用してリクエスト間でオブジェクトを保存できます。その後、オブジェクトの整合性を維持する方法が必要です。 これは合理的な議論です。 しかし、Doctrineでのエンティティのシリアル化は非常にトリッキーであり、深刻な問題につながる可能性があります。



IDマップはステートレス環境では役に立たない



アイデンティティマップはエンティティの一意性を維持するDoctrineの一部です。 たとえば、ID 4のエンティティを2回リクエストすると、同じオブジェクトを2回取得します。



一見、素晴らしいアイデアのように見えます。 しかし、孤立した実行の本質は何ですか?







ドクトリンアイデンティティマップは、デザインが不十分な場合にのみ有用であるように思えます。 または非常にまれで特別な場合。



UnitOfWorkが複雑すぎます



UnitOfWorkはDoctrine ORMの主要部分の1つです。 役に立たないと言っているわけではありませんが、複雑すぎます。 セッションとシリアル化の問題についてはすでに説明しました。 エンティティ管理は複雑なものであり、実装の複雑さに我慢できます。 この点を実現するのはかなり困難です。



しかし、私が我慢できないのは、「遅延」ロードおよび変更追跡ポリシーのためにほとんどの困難が生じたという事実です。



遅延読み込みは無意味です



「ステートレス」環境では、遅延読み込みは悪い習慣です。 これに追加するものは何もありません。 これによりパフォーマンスがわずかに向上する場合がありますが、これは非常にまれです。 では、なぜこれがDoctrine ORMの中心概念の1つなのでしょうか?



私がDoctrineを使用してチームと話すたびに、彼らはスタートアップの悪用が原因で問題が発生したことを認めています。 そして、これは経験豊富な開発者でも起こります。



私のクライアントの1人に対して、遅延読み込みの使用を検出して削除するロガーを作成しました。 これは無価値の露骨な例です。



変更追跡ポリシー



データの整合性を確保するために、このような複雑なシステムが必要なのはなぜですか? 私たちは「状態の保存なし」に囲まれています! アプリケーションのアーキテクチャが優れている場合、データはランダムな場所で変更されません。 まれなケース(ロギング、最後の接続時間の更新など)を除き、POST要求に従ってデータを変更するだけです。 その後、すぐにユーザーを別のページにリダイレクトします。



では、なぜこのような複雑なシステムが必要なのでしょうか? 設計が不十分なアプリケーションを非表示にするには?



EntityManagerにはあまりにも多くの魔法があります



グローバルEntityManagerは、他のORMオブジェクトと連携するFacadeパターンのように動作します。 これは、コード内のどこからでも呼び出すことができる非常に強力なツールです。



ただし、適切に設計されたアプリケーションでは、EntityManagerは次の3つの場合にのみ使用する必要があると強く信じています。







他の場所では、使用する必要はありません。



まだ興味深く強力なライブラリ



明確にするために、もう一度繰り返します。DoctrineORMは役に立たないと言っているのではありません。 私が一番気になるのは、図書館が悪い習慣を課していることです。







次は?



元の記事の著者は、Doctrineについてのいくつかの記事の資料を持っています。 たとえば、ODM拡張機能やジェネレーターについて。 さらに、彼はコメントの申請を受け入れます。



All Articles