Modelos gordos y controladores delgados suena como crear modelos de Dios [cerrado]

91

He estado leyendo muchos blogs que abogan por el enfoque de modelos gordos y controladores flacos , especialmente. el campamento Rails. Como resultado, los enrutadores básicamente solo están averiguando qué método llamar en qué controlador y todo lo que hace el método del controlador es llamar al método correspondiente en el modelo y luego abrir la vista. Entonces tengo dos preocupaciones aquí que no entiendo:

  1. El controlador y el enrutador en realidad no están haciendo tareas muy diferentes más que simplemente llamar a un método en el modelo similar a Dios basado en la ruta.
  2. Los modelos están haciendo demasiado. Enviar correos electrónicos, crear relaciones, eliminar y modificar otros modelos, hacer cola de tareas, etc. Básicamente, ahora tiene objetos tipo Dios que se supone que hacen todo lo que puede o no preocuparse por modelar y manejar datos.

¿Dónde se traza la línea? ¿No es esto simplemente caer en el patrón de Dios?

Cazador de la selva
fuente

Respuestas:

136

Puede que no sea la mejor idea considerar Rails como un elemento básico del patrón de diseño MVC. Dicho marco se creó con algunas deficiencias inherentes (lo elaboré un poco en una publicación diferente ) y la comunidad recién ahora ha comenzado a abordar las consecuencias. Podría considerar el desarrollo de DataMapper2 como el primer paso importante.

Alguna teoria

Las personas que dan ese consejo parecen estar afectadas por una idea errónea bastante común. Permítanme comenzar por aclararlo: el modelo, en el patrón de diseño moderno de MVC, NO es una clase u objeto. El modelo es una capa.

La idea central detrás del patrón MVC es la separación de preocupaciones y el primer paso es la división entre la capa de presentación y las capas del modelo. Al igual que la capa de presentación se divide en controladores (instancias, responsables de manejar la entrada del usuario), vistas (instancias, responsables de la lógica de la interfaz de usuario) y plantillas / diseños, también lo hace la capa de modelo.

Las partes principales que componen la capa del modelo son:

  • Objetos de dominio

    También conocidas como entidades de dominio, objetos de negocio u objetos de modelo (no me gusta ese último nombre porque solo aumenta la confusión). Estas estructuras son lo que la gente suele llamar erróneamente "modelos". Son responsables de contener las reglas comerciales (todas las matemáticas y la validación de una unidad específica de lógica de dominio).

  • Abstracciones de almacenamiento:

    Generalmente se implementa utilizando un patrón de mapeador de datos (no lo confunda con los ORM , que han abusado de este nombre). Estas instancias suelen tener la tarea de almacenar y recuperar información en los objetos de dominio. Cada objeto de dominio puede tener varios mapeadores, al igual que existen varias formas de almacenamiento (DB, caché, sesión, cookies, / dev / null).

  • Servicios:

    Estructuras responsables de la lógica de la aplicación (es decir, interacción entre objetos de dominio e interacción entre objetos de dominio y abstracciones de almacenamiento). Deben actuar como la "interfaz" a través de la cual la capa de presentación interactúa con la capa del modelo. Esto suele ser lo que en el código tipo Rails termina en los controladores.

También hay varias estructuras que pueden estar en los espacios entre estos grupos: DAO , unidades de trabajo y repositorios .

Oh ... y cuando hablamos (en contexto de web) sobre un usuario que interactúa con la aplicación MVC, no es un ser humano. El "usuario" es en realidad su navegador web.

Entonces, ¿qué pasa con las deidades?

En lugar de tener algún modelo aterrador y monolítico con el que trabajar, los controladores deberían interactuar con los servicios. Pasas datos de la entrada del usuario a un servicio específico (por ejemplo, MailServiceo RecognitionService). De esta forma, el controlador cambia el estado de la capa del modelo, pero se hace mediante el uso de una API clara y sin alterar las estructuras internas (lo que provocaría una abstracción con fugas).

Dichos cambios pueden causar una reacción inmediata o solo afectar los datos que la instancia de vista solicita de la capa del modelo, o ambos.

Cada servicio puede interactuar con cualquier número (aunque, por lo general, es solo un puñado) de objetos de dominio y abstracciones de almacenamiento. Por ejemplo, RecogitionServiceno podría importarle menos las abstracciones de almacenamiento de los artículos.

Notas de cierre

De esta manera, obtiene una aplicación que se puede probar unitariamente en cualquier nivel, tiene un bajo acoplamiento (si se implementa correctamente) y tiene una arquitectura claramente comprensible.

Sin embargo, tenga en cuenta: MVC no está diseñado para aplicaciones pequeñas. Si está escribiendo una página de libro de visitas usando el patrón MVC, lo está haciendo mal. Este patrón está destinado a hacer cumplir la ley y el orden en aplicaciones a gran escala.

Para las personas que usan PHP como idioma principal, esta publicación puede ser relevante. Es una descripción un poco más larga de la capa del modelo con algunos fragmentos de código.

tereško
fuente
¡Respuesta muy útil y completa! ¿Conoces algún libro que explique un poco más el patrón arquitectónico MVC? Especialmente en la parte de los modelos que todo el mundo piensa erróneamente "El modelo representa los datos y no hace nada más". y eso suena más a la idea de objeto de dominio, no al 'Modelo' -> tomdalling.com/blog/software-design/…
thermz
1
@thermz, afaik , realmente no hay libros que se ocupen exclusivamente del patrón MVC. Por lo general, le digo a la gente que lea PoEAA y luego vaya a investigar. Quizás esta lista de enlaces pueda ser útil. Encuentro que, cuando la gente tiene una sólida comprensión de los principios y conceptos de la programación orientada a objetos, el patrón se vuelve bastante fácil de entender.
tereško
@ tereško hermosa respuesta. ¿Hibernate logra esto? No estoy convencido por las respuestas aquí -> stackoverflow.com/questions/1308096/…
Ankan-Zerob
@ Ankan-Zerob, como puede notar, no soy un desarrollador de Java, pero por lo que sé sobre Hibernate, proporciona un conjunto de herramientas completo para la capa de persistencia. Le dará parte de lo que se describe allí, pero no una capa de modelo completa.
tereško
3
@johnny no que yo sepa. La mayoría de los llamados "frameworks mvc" de php son variaciones de Rails. Y, como parte del curso, la mayoría de ellos vienen con algunas soluciones de ORM basadas en registros activos (esas cosas son notoriamente frágiles para los cambios en la base de datos). Usted puede implementar algo como esto con SF2.x o ZF2.x, pero el punto de un marco no es para implementar / hacer cumplir una arquitectura específica, sino proporcionar herramientas. Además, cuando se trata de MVC, se implementa mediante el código de la aplicación y no el marco.
tereško
5

Si las clases "modelo" están mal implementadas, sí, su preocupación es relevante. Una clase modelo no debería estar haciendo correo electrónico (tareas de infraestructura).

La verdadera pregunta es qué implica el modelo en MVC. No está restringido a las clases POCO con algunos métodos. Modelo en MVC significa lógica de datos y negocios. Trátelo como un superconjunto de modelos POCO básicos clásicos.

Ver ==== Controlador ==== Modelo ---> Capa de proceso empresarial -> Modelos centrales

Agregue ensamblajes de infraestructura y capas de acceso a datos y use la inyección para entregar eso en el BPL, entonces su proceso está usando MVC según lo previsto.

BPL puede invocar patrones UoW / Respository, ejecutar reglas comerciales y llamar a funciones de infraestructura mediante objetos inyectados o patrones de interfaz.

Por lo tanto, la recomendación de mantener un controlador delgado no significa que la clase "persona" en un modelo Core clásico deba tener 50 métodos y llamar al correo electrónico directamente. Tienes razón al pensar que esto está mal.

Es posible que el controlador aún tenga que crear instancias e inyectar clases de infraestructura en la BPL o la capa central si se llama directamente. Debe haber una capa empresarial o al menos clases que orquestren las llamadas en las clases del modelo de objetos clásicos. Bueno, esa es mi "vista" de todos modos ;-)

Para una versión genérica de MVC, la descripción wiki http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Un pequeño blog que habla de la "M" en MVC. http://www.thedeveloperday.com/skinny-controllers/

Phil Soady
fuente
1
Si no está de acuerdo, al menos, ser educado lo suficiente para justificar su punto de vista
Phil soady
-1

Creo que puede hacer una distinción entre un solo modelo gordo (posiblemente llamado Aplicación o Aplicación) y varios modelos gordos divididos en grupos lógicos (Negocio, Cliente, Pedido, Mensaje). Esto último es cómo estructuro mis aplicaciones, y cada modelo corresponde aproximadamente a una tabla de base de datos en una base de datos relacional o colección en una base de datos de documentos. Estos modelos manejan todos los aspectos de la creación, actualización y manipulación de los datos que componen el modelo, ya sea hablando con la base de datos o llamando a una API. El controlador es muy delgado, responsable de un poco más de llamar al modelo apropiado y seleccionar una plantilla.

Bryan Young
fuente