Cuándo hacer el modelo de datos

Si me preguntasen por el mínimo común denominador de la aplicación de las metodologías tradicionales que he visto en los últimos años, respondería sin dudar el modelo de datos. La gestión de los requisitos es muy variable, el diseño y la construcción varían enormemente... Sin embargo, el momento y la forma en que se hace el modelo de datos siempre era la misma. Una vez recogidos los requisitos, durante el análisis, el paso clave que marcaba, en cierto modo, el fin del trabajo del analista y el comienzo del resto, era la validación del modelo de datos.

En las metodologías tradicionales se hace en dos partes: en la fase de análisis se hace el modelo lógico, y en diseño se hace el físico. En la práctica siempre he visto que esto se fusionaba. Quizá por las herramientas, quizá por lo innecesario de la división, siempre se hace directamente el segundo.

Desde que uso Hibernate había querido aprovechar al máximo la potencia de su mapeo relacional, relegando el modelo de datos a un segundo plano en favor del modelo de clases. Esto, que parece un detalle menor, en mi opinión tiene una gran importancia práctica. Hacerlo implicaría que el analista/diseñador haría, en vez del modelo, directamente las clases, las cuales generarían el primero automáticamente. Expuse esta idea esgrimiendo una serie de ventajas:

  • El trabajo de modelado aportaría más información, ya que los modelos Java más las anotaciones de persistencia aportan más información y valor que las tablas (se introducen validaciones de datos, propiedades calculadas, documentación...).
  • Eliminaríamos el problemático trabajo de mapear tablas existentes.
  • Adelantaríamos el trabajo de la programación de las entidades.
  • Podríamos anticipar cosas como pruebas automáticas para verificar la corrección del modelo.
  • Personalmente trabajo mejor con una herramienta de desarrollo que con una de modelado. Andar con el ratón, dobles clicks y diálogos me parece engorroso y lento, aunque esto ya son preferencias de cada uno.
  • No renunciamos a la información gráfica, ya que podemos generar diagramas tanto de clases como de objetos mediante ingeniería inversa (NetBeans es realmente útil para esto).
La idea no prosperó, y los siguientes proyectos se hicieron como anteriormente.

Al pasar a metodologías ágiles, al desaparecer estas fases, toca decidir cuándo realizar este trabajo. Scrum obviamente no entra en esta decisión, así que, ya con la capacidad de decisión, me adherí al principio de diseño contínuo y además adopté las ideas anteriores. De esta forma, no se haría el trabajo explícito de modelado de los datos, sino que, a medida que se avanzase en la aplicación, se iría mejorando a través del propio diseño de las clases.

Ya con el proyecto en desarrollo, saco las siguientes conclusiones:
  • No realizar análisis del modelo de datos, sino trabajar directamente en el diseño de las clases, es muy práctico: es mucho más tolerante a los cambios (hemos pasado de claves deferred a compuestas de forma trivial, por ejemplo), facilita el trabajo en equipo (no más "lanza de nuevo el script de base de datos, que he cambiado el esquema")... Me reafirmo, por tanto, en los puntos expuestos antes.
  • Desaparece la mentalidad de "tenemos que ceñirnos al modelo de datos a cualquier coste". He visto auténticos malabarismos por parte de desarrolladores por querer respetar el modelo del analista por todos los medios. El hecho de no tenerlo tira esa barrera.
  • Pese a esto, sigue siendo necesario hacer un trabajo previo de análisis. Comprender las clases y las relaciones entre ellas es fundamental para el desarrollo del proyecto. No es necesario especificar desde un principio cada propiedad de cada clase, sus longitudes máximas y sus validaciones, pero sí es importante tener claro lo antes posible el esquema general. Los desarrolladores tendemos a centrarnos en "pantallas", y en una no está la auténtica lógica de las relaciones entre los datos.
Para el siguiente proyecto estoy pensando incluso en hacer una primera versión del modelo de clases en el primer Sprint Meeting. En este creamos una tarea específica para ello, pero esto hace que el conocimiento quede en una sola persona. Creo que el trabajo de hacer una primera aproximación, incluso antes de la estimación de las tareas, ayudaría a todo el equipo a comprender el problema a resolver y la complejidad del desarrollo.

Posted by Juan Ignacio Sánchez Lara 15:15  

5 Comments:

  1. Ubersoldat said...
    Totalmente de acuerdo, te puedes encontrar o hacer verdaderas barbaridades, sobre todo en la capa DAO. Prefiero picar 1000 lineas de código, antes de pedirle a un DBA que cambie algo en la BBDD.
    Por otra parte, el problema de un ambiente tan dinámico, puede hacer que el cambio en una entidad rompa el modelo que otra aplicación está utilizando.
    javigs said...
    Yo he llegado a tener en un campo no usado de observaciones una ampliación de campos de la tabla separando cada uno de los campos con comas, vamos otra tabla CSV dentro de un campo de una tabla.

    Espero no tener que volver ha hacer "eso".
    AcP said...
    Opinando "en abstracto" justificaría un modelo de base de datos fuertemente establecido en fases tempranas del proyecto (hago malabarismos para que no suene a "ciclo de vida") diciendo que la base de datos modela el mundo real, mientras que el código modela el flujo de datos.

    Es decir que las tablas y sus relaciones representan objetos físicos o virtuales en un dominio de negocio. Estos no se modifican muy seguido. La base de datos debería ser, entonces, más estable. Típico ejemplo: una factura. Sería raro que cambien los datos o su estructura. Más bien cambiará el momento, o las personas que operen sobre o consulten esos datos.

    Eso en abstracto. En la vida real, según mi experiencia, las modificaciones a la base provienen no tanto de modificaciones en el negocio sino del aprendizaje, de la corrección o el ajuste fino a medida que vamos conociendo ese negocio, cuyos objetos (no el flujo de éstos a lo largo de las operaciones) siempre fueron los mismos, solo que no los conocíamos.

    Humilde conclusión: esquemas del tipo Hibernate son excelentes herramientas si estamos aprendiendo un negocio.
    Si estamos modelando un sistema cuyo negocio ya conocemos bastante bien yo elegiría un enfoque más tradicional: una base bien establecida y el código adaptándose a ella (o mejor dicho, dejándose modelar por ella). Perdemos velocidad frente a los cambios, por supuesto, pero el código es más simple y en todo caso no esperamos que hayan muchos en este sentido.

    Aclaro que lo anterior no es una opinión tajante ni mucho menos. Es un tema interesante, y muy... "gris", diría, así que se me deben estar escapando muchos detalles.
    Nacho said...
    @Ubersoldat: Sí, lo de la "intocabilidad" del esquema es un problema. Y no sólo hablamos de cambios, sino también de errores (que a veces no pensamos que los cometemos :) ).

    @javigs: Todos tenemos batallitas de esas. La tabla de usuarios suele ser la que disfruta de más "reingeniería creativa".

    @AcP: al hablar de modelado de clases me refería exclusivamente a las entidades, que en mi opinión modelan el mundo real, mejor que símplemente el modelo de datos. Por ejemplo, hacer las relaciones bidireccionales o no, anotar una relación con @OneToMany, @ManyToOne o @ManyToMany, o añadirle la transitividad de persistencia (@Cascade), proporciona mucha información sobre puramente los datos y sus relaciones que las tablas.

    Comprendo tu postura en función del conocimiento del negocio, y también opino que es discutible, pero no la comparto, ya que no creo que me aporte nada partir de la base de datos. De hecho, el código, lejos de simplificarse, se complica, ya que es necesario especificar el mapeo (nombres de tablas, de columnas, claves compuestas...) que de otra forma vendría dado.
    AcP said...
    Pensando sólo en entidades... realmente son dos caminos casi equivalentes...

    Lo que no tiene sentido, como bien apuntás, es modelar en dos lugares, quedarse a mitad de camino: utilizar una herramienta para crear y documentar la base de datos y luego mapear a entidades agregando información que falta en la herramienta, eso no hace más que dispersar la información.

    Antes que eso, coincido, es preferible crear las entidades y que la base de datos se cree automáticamente a partir de éstas.

    O el camino inverso: Es decir, partimos de la base y con una herramienta de generación de código creamos las entidades, que son fiel reflejo de ésta, sin aportar ni sacar nada.

    Así puesto es cuestión de qué herramienta nos es más cómoda o nos da más posibilidades para modelar: una tipo DER o entidades+anotaciones.

Post a Comment