Entender MVC: ¿Cuál es el concepto de “grasa” en los modelos, “flaco” en los controladores?

Estoy tratando de entender el concepto de “grasa” en los modelos frente a “flaco” en los controladores y de lo que he estado discutiendo tengo el siguiente ejemplo (esto se toma de una discusión freenode):

P: En el paradigma MVC, se dice que los modelos Fat, los controladores delgados. Estoy pensando, si tengo muchos métodos (en el controlador) que usan solo unos pocos métodos abstractos para CRUD (en el modelo), ¿estoy creando un controlador de grasa en lugar de un modelo? ¿O dicen, modelo gordo, referirse a lo que se devuelve y no se escribe? eso es algo que nunca he entendido =) ¡Cualquier comentario es apreciado! Muchas gracias

OBS1: No estoy haciendo lo que dice el modelo, en el controlador, solo tengo métodos que controlan qué va al modelo

OBS2: digamos “checkIfEmailExists ()”, tiene “[email protected]”, como parámetros. Este método obtendrá el retorno del método del modelo que pregunta si este parámetro existe en la tabla, return boolean. Si es 0, “checkIFemailExists ()” llamará a un método de modelo diferente, este, es solo otro método abstracto, que realiza la operación de actualización.

OBS3: el “checkIfEmailExists ()”, ¿no es solo un controlador? En realidad, él no está realizando ningún CRUD, solo está comparando valores, etc. Eso es lo que me está confundiendo, porque en mi cabeza este es un controlador: S

Notas: Supongo que este no es el mejor ejemplo, ya que decir “verificar si algo existe”, suena como una consulta de la operación de mi tabla

P2: solo una pregunta más, entonces, digamos que tengo un formulario de vista, desde donde se envía ese parámetro de dirección de correo electrónico. ¿Estás diciendo que la vista va directamente al modelo?

P3: ¿No debería el controlador actuar entre ellos? ese es el paradigma

NOTA FINAL: La discusión terminó, diciendo que estoy equivocado, deseo está bien (estoy aprendiendo). Pero, entonces, ¿cuál es la respuesta correcta para Q2 y Q3?

Gracias por tu atención

Su aplicación es la M. Debe ser independiente de V y C. V y C forman la interfaz de usuario para su aplicación. Si esta es una interfaz web o una interfaz de línea de comando no debería importar para la lógica de negocio principal de su aplicación. Usted quiere que el modelo esté gordo con lógica comercial.

Si tiene un controlador de grasa en su lugar, por ejemplo, lleno de lógica comercial, no se está adhiriendo al propósito de MVC. La única responsabilidad de un controlador es manejar y delegar las solicitudes de UI al Modelo. Es por eso que debe ser flaco. Solo debe contener el código necesario para lo que es responsable.

Ejemplo simplificado

public function fooAction() { if(isset($_POST['bar'])) { $bar = Sanitizer::sanitize($_POST['bar']); $rows = $this->database->query('SELECT * from table'); try { foreach($rows as $row) { $row->foo = $bar; $row->save(); } } catch (Exception $e) { $this->render('errorPage'); exit; } $this->render('successPage'); } else { $this->render('fooPage'); } } 

Cuando debería ser

 public function fooAction() { if(isset($_POST['bar'])) { $success = $this->tableGateway->updateFoo($_GET['bar']); $page = $success ? 'successPage' : 'errorPage'; $this->render($page); } else { $this->render('fooPage'); } } 

porque eso es todo lo que el controlador necesita saber. No debería actualizar las filas. Debería decirle al modelo que alguien solicitó este cambio. La actualización es responsabilidad de la clase que administra las filas. Además, el controlador no necesariamente tiene que desinfectar el valor.

En cuanto a Q2 y Q3, consulte mi respuesta a ¿Puedo llamar un Modelo desde la Vista ?

He estado trabajando con el paradigma de MVC durante mucho tiempo y puedo compartir con ustedes mi experiencia.

La parte “modelo” es responsable de manejar todo lo que no es estrictamente “web”, como validación, lógica, acceso a datos, etc. Piénselo como una especie de capa mixta de negocios + capa de acceso a datos. También puede tener BLL + DAL en ensamblajes separados y usar la parte “Modelo” de MVC como puente entre su BLL y su Aplicación, además de agregar clases que son específicas de la aplicación MVC y no relacionadas con el BLL, como las clases ViewData. , etc.

La parte de “controlador” es la que se encarga de las cosas específicas de la web, como autenticación, cookies, GET y POST, querystrings, etc. Utiliza las cosas presentes en el modelo y / o el BLL y envía los datos que se deben procesar para el usuario a las vistas.

Las “vistas” son sus plantillas html que pueden recibir datos del controlador y mostrarlos. Nunca se deben realizar operaciones lógicas en las vistas, por lo tanto, no hay enunciados “si”, no hay bucles, etc. Si tiene esas necesidades, entonces necesita algunos métodos “auxiliares” que creen el html deseado y luego los llame desde el ver. Por lo tanto, las vistas solo reciben datos y ofrecen al usuario enlaces / formularios para publicar los datos en un controlador, pero no detallan nada.

Espero que esto aclare algunas de tus dudas.

Siempre he interpretado que eso significa que los modelos deben encapsular la lógica relacionada con esos modelos en un enfoque más orientado a objetos, en lugar de tener toda la lógica en los controladores en un enfoque más procedimental. Para citar La Catedral y el Bazar :

Las estructuras de datos inteligentes y el código tonto funcionan mucho mejor que al revés.

Es posible que esté mostrando mi sesgo (hacia C #), pero no creo que tenga mucho sentido hablar de MVC a menos que esté utilizando un estilo de progtwigción orientado a objetos. Un controlador no es un método, es una colección de métodos agrupados en una clase, cada uno de los cuales maneja alguna entrada (url / solicitud). Un modelo no es una forma de acceder a la base de datos (es una capa de acceso a datos), es una colección de propiedades y métodos que encapsulan una entidad identificable en su aplicación: una persona, una reserva, un producto, etc. La mejor manera de piense en ello es que los controladores manejan la entrada, los modelos contienen datos, pero, por supuesto, eso está simplificado.

La cuestión de “Fat” versus “Skinny”, para mí, es la cuestión de dónde vive su lógica comercial. Si tienes mucha lógica en tu controlador relacionado, no solo para manejar entradas, sino también para implementar la lógica de negocios, entonces tu controlador es relativamente más grueso que si simplemente las usas para traducir solicitudes en ensamblajes de modelos que se transfieren a una vista para renderizar . En mi experiencia, no siempre es una decisión de ambos. Muchas veces tiene lógica de negocios (validación, mantenimiento de relaciones, auditoría) en el modelo mientras tiene lógica de aplicación (validación de permisos, desinfección, etc.) también en el controlador.

Creo que se puede hacer una buena separación entre el controlador y el modelo al permitir que el controlador realice operaciones dependientes “sintácticas” sin involucrar a ninguna lógica empresarial y utilizar el modelo para realizar operaciones relacionadas con la “semántica”.

Un buen ejemplo de esa separación es:

Puede realizar la comprobación de expresiones regulares de un correo electrónico en el controlador, pero no realizará la coincidencia de ese correo en el controlador.