Encontré un interesantísimo pasaje que me gustaría compartir. Trata sobre la Herencia en clases para la unificación de tablas en su estandarización en modelos complejos de persistencia y locales.

Resumidamente, la Herencia es una de las grandes cualidades de los Paradigmas Relacionales y de la Orientación a Objetos. Se basa en crear un objeto que contiene atributos que sus heredados compartirán como propiedad, pero no como valor. Es así como se pueden crear arboles de herencia donde como desarrolladores, nos enfocaremos en utilizar la última clase de la rama (la hoja) del árbol, que contendrá todas las propiedades de sus clases padre.

Por ejemplo, un Mamifero cuenta con miembros (extremidades), ojos, orejas y pelo. Un Perro ya tiene todas esas caracteristicas porque es mamifero, y ademas tiene cola, y puede ladrar, asi que podemos definir que tan agudo es su ladrido. Un Gato tambien es mamifero, asi que comparte todo lo de un mamifero y tiene bigotes y puedes realizar saltos de cierta cantidad de metros. Un Chihuahua tiene todas las propiedades de un perro y todas las de un mamifero por consiguiente, pero no tiene las propiedades de los gatos. Esto es un ejemplo de herencia.

Consideremos entonces el siguiente ejemplo de herencia:

En resumidas cuentas, un Jugador tiene un Nombre. A su vez, un Futbolista y un Voleibolista son Jugadores, por lo que ya tienen nombres y a su vez el primero pertenece a un Club y el segundo tiene una Posición. Finalmente, un Portero es un Futbolista, por lo que ya tiene un club y a su vez, es un jugador, por lo que tiene un nombre y además, cuenta con una cantidad de Bloqueos de gol registrados.

Pese a que comúnmente se tiende a separar todo en tablas o clases según sea la aplicación; Fowler propone tres métodos para organizar los datos en una aplicación. Esto viene fuertemente sustentado en el desempeño de las aplicaciones y más actualmente, a los modelos MVC y aplicaciones de persistencia con Scaffolding.

Primer Método: Herencia de Tabla Única (Single Table Inheritance)

Una Tabla guarda todos los datos y se define una variable de Tipo.

Este método considera tomar todas las propiedades de todas las tablas heredadas y unirlas en una sola tabla, agregando un atributo Tipo, que es donde definiremos que tipo de jugador es en cuestión el almacenado en un registro de esta tabla.

La Ventaja es tener todos los atributos de un jugador agrupados en un mismo objeto, lo que permite un acceso rápido y sin tanto código a los elementos que vayamos a utilizar. Además, todos los cambios que se hagan, se aplican automáticamente, evitando problemas de llaves foráneas o primarias. No obstante, la gran desventaja es que los campos no utilizados estarán ahí utilizando espacio del objeto (recordemos que un objeto puede ser dinámico, no sus atributos).

Es recomendable utilizar este método en aplicaciones donde los datos en su mayoría sean semejantes, a modo de poder aprovechar lo más posible los objetos generados.

Segundo Método: Herencia de Tablas Concretas (Concrete Table Inheritance)

Cada Clase utilizable se define en una tabla independiente con todas sus propiedades heredadas.

Para este método, se declaran las clases que efectivamente serán declaradas en la aplicación, incluyendo cada una las propiedades que heredan de sus clases padre. Este método permite mejor control sobre objetos puntuales y no provoca esa innecesaria pérdida de memoria al tener atributos inútiles gastando memoria como en el primer método.

El problema viene al momento de querer cambiar atributos que son heredados. Por ejemplo, si queremos eliminar la propiedad club de los futbolistas, deberemos también hacerlo para los porteros y al trabajar en un entorno de persistencia eso vuelve al código y a la aplicación menos mantenible, ya que debemos recordar todas las tablas donde haya que eliminar la propiedad. Eso puede traer problemas de integridad en una aplicación incluso pequeña.

Tercer Método: Herencia de Tablas de Clases (Class Table Inheritance)

Se define una tabla para cada clase y no se incluyen sus propiedades heredadas.

La forma más básica y simple de realizar la herencia: tener una tabla con los atributos particulares de cada objeto definible, más las claves de sus heredados o padres según corresponda. Es el modo que probablemente la mayoría trabaja, ya que separa claramente los diferentes objetos de la aplicación. El problema es que el uso de vinculadores (Joins) y llaves foráneas aquí se hace extensivo, además de tener que definir bien las propiedades de cascada al eliminar o modificar atributos.

Como se puede apreciar, no es tan trivial la forma de definir nuestras tablas al querer crear aplicaciones mantenibles y eficientes. Sin duda, una buena elección permitirá que nuestra aplicación sea más sostenible en el tiempo y que este menos expuesta a problemas de integridad, clásicos al llevar un proyecto de mediana complejidad.

Fuente: Patterns of Enterprise Application Architechture de Martin Fowler

2 thoughts on “Herencia en Tablas y Clases

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *