私たちのAPIには、計算された値でデータベースから取得した後に(いわば)「装飾」する必要があるいくつかの中心的なデータ型があります。データベースは、CakePHP 3データベースレイヤーから大きく影響を受けたTable/Entityダイナミックに従うORMを介してアクセスされます。Tableオブジェクトは、データベースと、モデルオブジェクトインスタンスとして行を取り込んで渡すアプリケーションとの間の仲介として使用されます。したがって、データベースからデータを取得してそれらの行を返すだけでなく、返されたデータを実際に使用する前に前処理する必要があります。ここに私が何を意味するかをよりよく説明するために出てきたいくつかのユースケースがあります:
単独では、これらのいずれも、返された結果セットに対する単純なmap()
操作を使用すると、実際にはかなり簡単に実行できます。同じことが複数の計算値が必要な場合にも当てはまります。必要に応じて、より多くのマップ操作を実行して、それらのフィールドを計算および追加できます。
つまり、このアプローチには2つの大きな欠点があります。
両方を処理するために、私はこのコードをORMに移動し、ORMを変更して、インターフェイスがデータベース列を処理するのと同じ方法で計算された仮想フィールドにアクセスできるようにすることが最善のアプローチであると考えていました。内部的には、これらの仮想フィールドを変換関数にマップし、潜在的に必要な依存関係変換を内部的に決定して、2番目の問題を解決することができます。
(余談ですが、これにより、単純なハッシュとは対照的に、返された行が実際のオブジェクトである必要がなくなるのではないかと思っています。現在、各行は、フィールドデータが設定された新しいオブジェクトをインスタンス化しますが、すべての計算またはデータの変更はモデルの外に移動され、オブジェクトはプロパティのバッグになります-本質的に、それ自体の内部ロジックを持たないハッシュマップです。これは実際には悪いことではないかもしれません)
前述のケースでは、リポジトリのようなレイヤーを使用できます。
[リポジトリ]ドメインオブジェクトにアクセスするためのコレクションのようなインターフェイスを使用して、ドメインとデータマッピングレイヤーの間を仲介します。
ケースごとに1つのリポジトリ。ORMを使用してデータを読み取り、データを強化して返します。
したがって、そのようなインスタンスにアクセスし、それらのインスタンスが外部から作成される方法を非表示にする1つの統合された方法があります。また、これにより、公開されたインターフェイスを変更することなく、ORMから生のSQLクエリに切り替えることができます。
@potfurに同意します。データベース内のデータを表す「データオブジェクト」とそれらの「ビジネス」表現の間で分割し、追加のロジックや計算などをカプセル化することは、正しい方向性です。特定のドメイン/ビジネスのデータがどのように表現され、技術的に保存されるかは、まったく異なる場合があります。ドメインを表すオブジェクトを使用してビジネスロジックを実装すると、顧客にとっての価値が高まり、コミュニケーションが容易になります。 ORMについては、スケーラビリティの問題について言及されています。 ORMはアンチパターンだと思います。小規模/中規模では非常に便利ですが、スケーラビリティに関しては失敗し始めます。あなたができることは、「ビジネスエンティティ」のキャッシュレイヤーを追加することです。そのため、毎回それらを計算する必要はありません。