Model-View-Controller

Qué organiza

Model-View-Controller (MVC) separa conocimiento y comportamiento del problema, representación e interpretación de la interacción. Su preocupación es organizar presentación: permitir cambiar una interfaz sin trasladar sus decisiones al resto de la aplicación. El nombre describe responsabilidades y colaboraciones; no determina por sí solo procesos, propiedad de datos o deployment.

En el Atlas es un Presentation Pattern, dentro de Frontend and Client Architecture. Puede existir en un monolith, un modular-monolith o un servicio de microservices. Esas elecciones describen otros compromisos. presentation-patterns compara MVC con model-view-presenter y model-view-viewmodel.

Origen y responsabilidades

Trygve Reenskaug formuló MVC en Xerox PARC en 1979, al trabajar sobre interfaces interactivas. Su nota del 10 de diciembre presenta Model como representación de conocimiento, View como perspectiva que consulta ese conocimiento y Controller como mediador de interacción. Incluso permite mensajes View → Model y Controller → View: no prescribe el circuito lineal que suele atribuirse a todo MVC. Models–Views–Controllers, documento original conservado en una copia pública; registro histórico ESUG/Zenodo.

PapelResponsabilidad conceptual
ModelEstado, operaciones y conocimiento del problema, independientes de una representación concreta.
ViewRepresentar información pertinente mediante una interfaz visible o interactiva.
ControllerInterpretar gestos o peticiones y coordinar su traducción a operaciones apropiadas.

Model no equivale a database table ni a ORM entity. Puede abarcar estado de dominio o aplicación, comportamiento, información necesaria para presentación y abstracciones ajenas al mecanismo de UI. Una entidad persistida puede participar, pero no agota esa responsabilidad.

View tampoco significa solamente HTML. Puede usar controles de escritorio, templates, UI markup, dibujo imperativo o composición declarativa. Una biblioteca puede reunir captura de eventos y rendering en un widget; separar responsabilidades no exige que cada gesto tenga una clase Controller nueva.

MVC clásico y sincronización

En formulaciones clásicas de GUI, View consulta u observa Model y Controller procesa la interacción. Los cambios notifican a las representaciones interesadas, que vuelven a consultar lo que necesitan mostrar. Fowler describe esta dinámica en Smalltalk-80, incluyendo colaboración entre controles y las dificultades de seguir actualizaciones indirectas. GUI Architectures, sección Model View Controller.

Un esquema introductorio posible es:

User → Controller → Model → View

Es una simplificación de un escenario, no la dirección universal de MVC. La última flecha puede representar una notificación seguida de una consulta; no necesariamente una llamada del Model que renderiza controles. Tampoco reproduce literalmente la nota de Reenskaug ni cada implementación posterior de Smalltalk.

unidirectional-data-flow examina la organización dirigida de cambios de estado, sin convertir esta simplificación en una ley de MVC ni declarar incompatibles todas sus variantes. rendering-strategies trata dónde y cuándo se produce representación Web; esa elección tampoco queda resuelta por nombrar Controller, Model y View.

La sincronización importa tanto como las cajas. Debe conocerse quién posee el estado editable, qué evento anuncia un cambio y cómo se conserva coherencia entre representaciones. Si dos Views mantienen copias independientes del mismo nombre, una notificación mal definida puede dejar una pantalla desactualizada aunque existan tres carpetas impecables.

No confundir flechas de ejecución con dependencias de código. Publicar un evento no requiere que el Model importe una clase concreta de pantalla. En una implementación debe explicitarse qué contrato permite esa comunicación y quién administra su suscripción y lifecycle.

MVC del servidor Web

Una aplicación Web suele organizar una secuencia diferente:

HTTP Request
→ Controller
→ Application / Model
→ View selection / rendering
→ HTTP Response

ASP.NET Core MVC documenta controllers que trabajan con Model, seleccionan View y entregan datos para rendering. Rails describe la instancia y acción que atienden una petición enrutada. Spring MVC se apoya en Servlet y su infraestructura de despacho. ASP.NET Core MVC, Action Controller en Rails, Spring Web MVC.

ASP.NET MVC, Rails y Spring MVC no son reproducciones exactas del MVC original de Smalltalk. Son adaptaciones al contexto Web, no implementaciones incorrectas por esa diferencia. La petición y respuesta no implican una View del servidor permanentemente suscrita al Model durante la interacción del navegador.

PreguntaGUI clásica, orientativamenteMVC Web del servidor, orientativamente
Unidad de interacciónGestos sobre controles persistentes.Petición atendida por una acción.
Actualización visibleObservación/consulta y repintado.Rendering de respuesta o navegación posterior.
Estado entre interaccionesObjetos de sesión de UI.Debe resolverse explícitamente entre peticiones.

Un cliente Web puede añadir comportamiento interactivo y su propia organización de presentación. Eso no permite deducir su patrón a partir del controller del servidor. Asimismo, una respuesta JSON puede omitir una View HTML sin resolver todas las preguntas sobre presentación del cliente.

Ejemplo común: Edit Customer

Este ejemplo propio también aparece en MVP y MVVM: cargar un cliente, editar su nombre, validar, guardar y mostrar éxito o error. Suponemos una operación de aplicación que recibe identificador y nombre propuesto, y devuelve aceptación, rechazo o conflicto. La tecnología de almacenamiento queda fuera del ejemplo.

En una variante MVC Web:

  1. El Controller de carga interpreta el identificador y solicita los datos a la aplicación.
  2. Selecciona una View que presenta el nombre y un formulario editable.
  3. Al guardar, otro request trae el nombre propuesto. El Controller traduce la entrada y delega validación y modificación autoritativas.
  4. Si hay rechazo, prepara datos de presentación conservando el texto ingresado y los errores. La View los renderiza.
  5. Si hay aceptación, selecciona una respuesta adecuada, por ejemplo una navegación hacia la versión confirmada con mensaje de éxito.

En una GUI clásica, Controller puede traducir la edición a cambios sobre un modelo editable; View consulta ese estado y observa resultados. No hace falta una petición HTTP por cada carácter. El borrador y el cliente confirmado deben distinguirse si cancelar edición significa descartar cambios.

Ese reparto evita esconder política de negocio en el rendering. Mostrar una validación inmediata mejora feedback, pero no sustituye la regla autoritativa al guardar. También evita perder el texto del usuario cuando una respuesta contiene errores: el estado mostrado no siempre coincide con lo ya persistido.

Controller, negocio y composición

Controller no es sinónimo de business logic ni de application service. Puede decidir cómo traducir una petición, seleccionar representación y coordinar interacción. La regla que decide si una modificación está permitida debe conservarse fuera de esa adaptación cuando otras entradas también la necesitan.

Por ejemplo, «Order no puede cancelarse después de shipment» debe cumplirse aunque la operación llegue por otro canal. Deshabilitar Cancel en la pantalla es una decisión de presentación derivada de la disponibilidad de la operación; no es su autoridad.

En layered-architecture, Controller puede delegar en Application y Domain. En ports-and-adapters, un HTTP Controller puede formar parte de un driving adapter que traduce el canal a un application port. MVC entero no se convierte automáticamente en un adaptador.

En clean-architecture, la organización UI puede conservar dependencias hacia contratos interiores mientras infraestructura implementa necesidades del núcleo. El flujo runtime hacia almacenamiento no autoriza imports inversos. MVC organiza interacción; esas aproximaciones gobiernan fronteras más amplias.

Costos y reconocimiento

La separación facilita variar representación y probar coordinación sin renderizar toda la UI. Tiene costos: traducciones, contratos, ownership del estado y sincronización. Un Controller que concentra todos los casos de uso puede convertirse en un punto de cambio excesivo.

Probar nuestro ejemplo requiere verificar delegación, conservación del borrador ante rechazo y selección de representación; también pruebas del formulario real, routing y mapping. Una prueba de Controller con colaboradores simulados no demuestra que la View muestre el error correcto.

Carpetas Controllers/Views/Models no prueban MVC. Los nombres de un framework tampoco fijan la definición histórica. Revisar responsabilidades, dependencias, interacción y estado permite reconocer qué variante existe y qué separación conserva.