In unserer API gibt es einige zentrale Datentypen, die nach dem Abrufen aus der Datenbank mit berechneten Werten (sozusagen) "dekoriert" werden müssen. Der Zugriff auf die Datenbank erfolgt über ein ORM, das einer stark von der CakePHP 3-Datenbankebene inspirierten Tabellen- / Entitätsdynamik folgt, bei der ein Tabellenobjekt als Vermittler zwischen der Datenbank und der Anwendung verwendet wird, die Zeilen als Modellobjektinstanzen ein- und ausgibt. Anstatt nur Daten aus der Datenbank abzurufen und diese Zeilen zurückzugeben, müssen wir die zurückgegebenen Daten vorverarbeiten, bevor sie tatsächlich verwendet werden können. Hier sind einige Anwendungsfälle, die aufgetaucht sind, um besser zu erklären, was ich meine:
- Objekte haben numerische Werte, die in benutzerfreundliche Bezeichnungen übersetzt werden (normalerweise ist dies eine Logik, die ich nur auf dem Client behalten würde, aber aus Gründen der Geschäftssicherheit müssen einige dieser Daten nur auf dem Server gespeichert werden, zugegebenermaßen ein bisschen Randfall)
- Objekten muss ein Bewertungswert zugeordnet sein, der aus der zuletzt hinzugefügten Bewertung gezogen wird
- Basierend auf einer Kombination aus solchen berechneten Werten und gespeicherten Werten wird ein komplexes Zeitplanobjekt erstellt
Alle diese Elemente sind für sich genommen mit einer einfachen map()
Operation über die zurückgegebene Ergebnismenge ziemlich einfach durchzuführen. Das Gleiche gilt, wenn Sie mehrere berechnete Werte wünschen. Sie können einfach mehr Kartenoperationen ausführen, um diese Felder nach Bedarf zu berechnen und hinzuzufügen.
Dieser Ansatz weist jedoch zwei Hauptnachteile auf:
- Dies bedeutet, dass Sie überall dort, wo Sie mit diesen berechneten Werten arbeiten möchten, einen zusätzlichen Schritt der Nachbearbeitung ausführen müssen, was nicht besonders trocken ist
- Einige dieser Transformationen hängen davon ab, dass andere Transformationen zuerst durchgeführt werden, andernfalls stehen ihnen einfach nicht die Daten zur Verfügung, mit denen sie arbeiten können
Um beides zu handhaben, habe ich mir überlegt, dass der beste Ansatz darin besteht, diesen Code in das ORM zu verschieben und dann das ORM so zu ändern, dass die Schnittstelle (extern) den Zugriff auf die berechneten virtuellen Felder auf die gleiche Weise ermöglicht, wie sie mit Datenbankspalten umgeht . Intern könnte es diese virtuellen Felder dann Transformationsfunktionen zuordnen und intern alle potenziell erforderlichen Abhängigkeitstransformationen bestimmen, um das zweite Problem zu lösen.
(Abgesehen davon frage ich mich, ob dies auch die Notwendigkeit beseitigt, dass die zurückgegebenen Zeilen tatsächliche Objekte sind, im Gegensatz zu einfachen Hashes. Im Moment instanziiert jede Zeile ein neues Objekt mit dem Felddatensatz darauf, aber wenn alle Berechnungen oder Wenn Änderungen an den Daten aus dem Modell verschoben werden, wird das Objekt zu einer Tasche mit Eigenschaften - eine Hashmap im Wesentlichen ohne eigene interne Logik. Was meiner Meinung nach möglicherweise keine schlechte Sache ist.