¿Modelos por tabla de base de datos?

11

Estoy usando codeigniter, y me he encontrado en una situación similar en la que he repetido métodos Model. Estoy creando un modelo por controlador. ¿Pero crear una tabla de Modelo por base de datos se consideraría una buena práctica? De esa forma, los métodos no se escriben dos veces.

En lugar de modelo por controlador o varios modelos pequeños que se comparten.

Ejemplo si tengo un método modelo get_user ($ user_id) podría escribirlo en users_models.php ...

Una de las desventajas que veo de esto es que podría tener que llamar a varios modelos, en lugar de solo controllername_models.php.

¿Podría cargar varios modelos en los que no se pueden usar varios métodos desde un controlador afectar el rendimiento y la velocidad? ¿Cuál podría ser la mejor manera de abordar esto?

Nota: Hay una pregunta similar, pero no cubren la base del Modelo por tabla de base de datos.

Howard Steff
fuente

Respuestas:

8

Digo que un modelo por tabla solo está recreando su base de datos en una estructura de clase. Se conoce como un modelo anémico y se considera un antipatrón. Esto se debe a que las clases están destinadas a tener datos y comportamiento. Si restringe sus modelos a una sola tabla, ¿dónde coloca el código (comportamiento) que necesita para tratar con los datos y el comportamiento de varias tablas? Sus controladores necesitarían modelos que usen uno o más de estos modelos de "tabla" ... Entonces, aparte de en las aplicaciones más básicas, gana poco o nada con este enfoque.

Marjan Venema
fuente
Solo un poco de un apéndice: Martin Fowler lo considera un antipatrón. Parada completa aquí. Tiene alguna idea sobre este caso, pero eso no significa que sea malo , a diferencia de God Object, que casi siempre es malo, una estructura como esta es a veces increíblemente útil y fácil de mantener. No considero que esto sea un antipatrón en absoluto.
T. Sar
1
Como ejemplo, el "modelo anémico" es SÓLIDO: ¿es realmente malo tener un objeto con un único propósito (almacenar datos)? Si bien respeto muchas cosas que dice el Sr. Fowler, esta fue una mierda.
T. Sar
7

En general, debe crear sus modelos no por tabla o por controlador, sino por objeto comercial. A veces puede ser una relación 1: 1 con la estructura de sus tablas o con sus controladores, pero no es necesario.

En su ejemplo, puede tener una users_modelclase que se llama desde varios controladores. Esto está bien y a veces incluso es deseable. Sin embargo, en la mayoría de los casos, la users_modelclase obtendrá sus datos de varias tablas.
Por ejemplo, la last_login_datepropiedad de la users_modelclase puede ( no debe ) obtenerse de una user_audittabla separada que tenga una relación de uno a muchos con la userstabla principal .

Y diría que si tiene una tabla SQL por objeto comercial, lo más probable es que la estructura de su base de datos no esté normalizada.

Moneda de diez centavos
fuente
3

En general, estoy de acuerdo con la respuesta de Dime de que desea crear sus modelos por objeto comercial: los problemas que la empresa está tratando de resolver deberían determinar cómo se crean las clases de modelos. En la práctica, he descubierto que crear un modelo por tabla es un buen lugar para comenzar. Es probable que un esquema diseñado adecuadamente imite los procesos comerciales que necesita modelar en el código de la aplicación, también denominado Modelo de dominio.

Usar una capa de mapeo de objeto / relacional es útil, por lo que su modelo de dominio contiene las mismas relaciones que el esquema de la base de datos sin la necesidad de llamadas repetitivas a una capa de acceso a datos. Mira Eloquent para PHP como ejemplo. Tanto el esquema como el modelo de dominio deben diseñarse para admitir los procesos comerciales.

Esto lleva a la primera parte de la respuesta de Marjan Venema:

Digo que un modelo por tabla solo está recreando su base de datos en una estructura de clase. Se conoce como un modelo anémico y se considera un antipatrón.

Un modelo de dominio anémico es un antipatrón. Un "modelo por tabla", como sugiere Venema, podría verse como "recreando su base de datos", sin embargo, es absolutamente incorrecto decir que solo es un modelo de dominio anémico.

De Martin Fowler:

El síntoma básico de un modelo de dominio anémico es que a primera vista parece real. Hay objetos, muchos con nombres de sustantivos en el espacio de dominio, y estos objetos están conectados con las relaciones y la estructura rica que tienen los verdaderos modelos de dominio. El truco se produce cuando observas el comportamiento y te das cuenta de que casi no hay comportamiento en estos objetos, lo que los convierte en poco más que bolsas de captadores y colocadores.

(énfasis, mío)

El factor clave en un modelo de dominio anémico es la falta de comportamiento o métodos en las clases del Modelo de dominio.

Esto se debe a que las clases están destinadas a tener datos y comportamiento. Si restringe sus modelos a una sola tabla, ¿dónde coloca el código (comportamiento) que necesita para tratar con los datos y el comportamiento de varias tablas?

Una vez más, puede y debe poner el comportamiento en sus Modelos de dominio, incluso si solo se asignan a una tabla. El comportamiento que afecta a varias tablas realmente afecta a varios objetos que se asignan a varias tablas. El diseño impulsado por dominio es un enfoque precisamente al mismo problema que Venema mencionó: "¿dónde coloca el código (comportamiento) que necesita para manejar los datos y el comportamiento de varias tablas?"

Y la respuesta es una raíz agregada . Martin Fowler afirma:

El agregado es un patrón en el diseño impulsado por dominio. Un agregado DDD es un grupo de objetos de dominio que se pueden tratar como una sola unidad. Un ejemplo puede ser un pedido y sus líneas de pedido, estos serán objetos separados, pero es útil tratar el pedido (junto con sus líneas de pedido) como un agregado único.

(énfasis, mío)

Un "grupo de objetos de dominio" también se puede ver como "Modelos de dominio que se asignan a varias tablas". El comportamiento que afecta a varias tablas debe definirse en la raíz agregada: una clase que encapsula la "cosa" que afecta a múltiples tablas u objetos:

De nuevo, de Martin Fowler:

Un agregado a menudo contendrá colecciones múltiples, junto con campos simples.

Para responder la pregunta original del OP:

... ¿se considera una buena práctica crear un modelo por tabla de base de datos? De esa forma, los métodos no se escriben dos veces.

Diría que este es un buen lugar para comenzar, pero tenga en cuenta que su esquema y modelo de objeto no tienen que coincidir al 100%. El modelo de objetos debería estar más preocupado por la implementación y el cumplimiento de las reglas de negocio. El esquema debería centrarse más en almacenar datos comerciales de forma modular y escalable.

Un modelo por controlador no sería una buena práctica, aunque existe una variación del modelo llamada Modelo de vista que se ajusta a la capa Controlador. Un modelo de vista es una reorganización del modelo de dominio para adaptarse a un determinado tipo de visualización, ya sea una página web o un formulario en una aplicación GUI.

Greg Burghardt
fuente