ORMで複雑な計算フィールドを処理する方法


8

私たちのAPIには、計算された値を持つデータベースから取得した後に(いわば)「装飾」する必要があるいくつかの中心的なデータ型があります。データベースは、CakePHP 3データベースレイヤーから大きく影響を受けたテーブル/エンティティダイナミックに従うORMを介してアクセスされます。テーブルオブジェクトは、データベースと、モデルオブジェクトインスタンスとして行を取り込んで渡すアプリケーションとの間の仲介として使用されます。したがって、データベースからデータを取得してそれらの行を返すだけでなく、返されたデータを実際に使用する前に前処理する必要があります。ここに私が何を意味するかをよりよく説明するために出てきたいくつかのユースケースがあります:

  • オブジェクトには数値があり、ユーザーフレンドリーなラベルに変換されます(通常、これは純粋にクライアントに保持するロジックですが、ビジネスセキュリティ上の理由から、このデータの一部はサーバーにのみ保持する必要があります。エッジケース)
  • オブジェクトには、最後に追加された評価から取得された関連する評価値が必要です
  • このような計算値と保存された値の組み合わせに基づいて、複雑なスケジュールオブジェクトが構築されます

単独では、これらのいずれもmap()、返された結果セットに対する単純な操作で実際にかなり簡単に実行できます。同じことが複数の計算値が必要な場合にも当てはまります。必要に応じて、より多くのマップ操作を実行して、それらのフィールドを計算および追加できます。

とはいえ、このアプローチには2つの大きな欠点があります。

  1. これは、これらの計算された値を操作するすべての場所で後処理の追加の手順を実行する必要があることを意味します。これは特にDRYではありません。
  2. これらの変換の一部は、最初に実行される他の変換に依存しています。それ以外の場合は、操作できるデータがありません。

両方を処理するために、このコードをORMに移動し、ORMを変更して、インターフェイスが(外部で)データベース列を処理するのと同じ方法で計算された仮想フィールドにアクセスできるようにするのが最善のアプローチであると考えていました。内部的には、これらの仮想フィールドを変換関数にマップし、潜在的に必要な依存関係変換を内部的に決定して、2番目の問題を解決することができます。

(余談ですが、これにより、単純なハッシュではなく、返された行が実際のオブジェクトである必要がなくなるかどうか疑問に思っています。現在、各行は、フィールドデータセットが設定された新しいオブジェクトをインスタンス化しますが、すべての計算またはデータの変更はモデルの外に移動され、オブジェクトはプロパティのバッグになります-本質的に、それ自体の内部ロジックを持たないハッシュマップです。これは実際には悪いことではないかもしれません)


これはどのように@moberemkに行きましたか?
Slamice 2016年

ORMが難しい場合は、ネイティブSQLクエリを使用できます。通常、ORMは安全なSQLクエリを実行する方法を提供します。これは、生のSQLで実行できる状況よりもすべての状況を処理できないことをよく知っているためです。
Walfrat 2016年

回答:


3

前述のケースでは、リポジトリのようなレイヤーを使用できます。

[リポジトリ]ドメインオブジェクトにアクセスするためのコレクションのようなインターフェイスを使用して、ドメインとデータマッピングレイヤーの間を仲介します。

ケースごとに1つのリポジトリ。ORMを使用してデータを読み取り、データを強化して返します。

したがって、そのようなインスタンスにアクセスし、それらのインスタンスがどのように外部から作成されるかを非表示にする1つの統合された方法があります。また、これにより、公開されたインターフェースを変更することなく、ORMから生のSQLクエリに切り替えることができます。


これは私がこのプロジェクトのために本質的にやったことですが、大規模なデータセットに対してこれで大きなパフォーマンスの問題があったことに注意したいです。基本的に、それは機能しますが、大規模ではありません。しかし、正確さのために受け入れます。
moberemk 2016年

0

@potfurに同意します。データベース内のデータを表す「データオブジェクト」と、それらの「ビジネス」表現の間で分割し、追加のロジックや計算などをカプセル化することは、正しい方向性です。特定のドメイン/ビジネスのデータがどのように表現され、技術的に保存されるかは、まったく異なる場合があります。ドメインを表すオブジェクトを使用してビジネスロジックを実装すると、顧客にとっての価値が高まり、コミュニケーションが容易になります。ORMについては、スケーラビリティの問題について言及されています。ORMはアンチパターンだと思います。小規模/中規模では非常に便利ですが、スケーラビリティに関しては失敗し始めます。あなたができることは、「ビジネスエンティティ」のキャッシングレイヤーを追加することです。そのため、毎回それらを計算する必要はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.