Cómo manejar campos calculados complejos en un ORM

8

En nuestra API tenemos algunos tipos de datos centrales que deben ser "decorados" (por así decirlo) después de la recuperación de la base de datos con valores calculados. Se accede a la base de datos a través de un ORM que sigue una dinámica de tabla / entidad inspirada en gran medida en la capa de base de datos CakePHP 3, donde se utiliza un objeto de tabla como intermediario entre la base de datos y la aplicación que toma y entrega filas como instancias de objetos modelo. Entonces, en lugar de simplemente recuperar los datos de la base de datos y devolver esas filas, necesitamos preprocesar los datos devueltos antes de que realmente sean utilizables. Aquí hay algunos casos de uso que han surgido para explicar mejor lo que quiero decir:

  • Los objetos tienen valores numéricos que se traducen en etiquetas fáciles de usar (normalmente esta es una lógica que mantendría únicamente en el cliente, pero por razones de seguridad empresarial, algunos de estos datos solo deben guardarse en el servidor, sin duda una poco de un caso de borde)
  • Los objetos deben tener un valor de calificación asociado que se extraiga de la clasificación agregada más recientemente
  • Sobre la base de una combinación de valores calculados como este y valores almacenados, se construye un objeto de programación complejo

Por sí solos, cualquiera de estos individualmente es realmente fácil de hacer con una simple operación map() sobre el conjunto de resultados devueltos. Lo mismo se aplica cuando desea múltiples valores calculados, simplemente puede hacer más operaciones de mapa para calcular y agregar esos campos según sea necesario.

Dicho esto, este enfoque tiene dos inconvenientes principales:

  1. Significa que debe realizar un paso adicional de postprocesamiento en todos los lugares donde desee trabajar con estos valores calculados, que no está particularmente SECO
  2. Algunas de estas transformaciones dependen de otras transformaciones que se realizan primero, de lo contrario, simplemente no tienen los datos disponibles para trabajar con

Para manejar ambos, he estado pensando que el mejor enfoque sería mover este código al ORM, luego modificar el ORM para que la interfaz (externamente) permita el acceso a los campos virtuales calculados de la misma manera que se trata. con columnas de la base de datos. Internamente, luego podría asignar estos campos virtuales a funciones de transformación, y determinar internamente cualquier posible transformación de dependencia necesaria para resolver el segundo problema.

(Dejando de lado, me pregunto si esto también elimina la necesidad de que las filas devueltas sean objetos reales en lugar de simples hashes. Ahora, cada fila crea una instancia de un nuevo objeto con el campo de datos establecido en él, pero si Todos los cálculos o modificaciones de los datos se eliminan del modelo y, a continuación, el objeto se convierte en una bolsa de propiedades: un mapa de hash, esencialmente, sin una lógica interna propia. Lo que en realidad no es algo malo, creo)

    
pregunta moberemk 29.06.2015 - 17:36

2 respuestas

3

Puede usar una capa similar a un repositorio para los casos mencionados anteriormente.

  

[Repositorio] Media entre el dominio y las capas de asignación de datos utilizando una interfaz similar a una colección para acceder a objetos de dominio.

Un repositorio por caso, que utiliza ORM para leer datos, los enriquece y devuelve.

Por lo tanto, tendría una forma unificada de acceder a dichas instancias y ocultar cómo se crean esas instancias desde afuera. Además, esto le permitiría cambiar de ORM a consultas de SQL sin modificar la interfaz expuesta.

    
respondido por el potfur 23.03.2016 - 23:33
0

Estoy de acuerdo con @potfur. La división entre los "objetos de datos", que representan los datos en la base de datos, y su representación "comercial", encapsulando lógica adicional, cálculo, etc., es en mi opinión la dirección correcta. La forma en que se representan los datos para un determinado dominio / negocio y lo que luego se almacena técnicamente puede ser algo completamente diferente. Implementar la lógica empresarial con objetos que representan el dominio ayuda a agregar el valor para el cliente y facilita la comunicación. En cuanto al ORM, mencionas problemas de escalabilidad. Creo que un ORM es un anti-patrón. Aunque es muy útil en escala menor / media, cuando se trata de escalabilidad, comienza a fallar. Lo que podría hacer es agregar una capa de almacenamiento en caché para las "entidades empresariales", para que no tenga que calcularlas cada vez.

    
respondido por el David Lukac 26.03.2016 - 22:25

Lea otras preguntas en las etiquetas