MVC: la esencia del patrón Model-View-Controller y su implementación

Autor: IT Sectr Publicado: 2026-02-16 Tiempo de lectura: 9 min

MVC (Model-View-Controller) es un patrón arquitectónico que divide una aplicación en tres componentes: Model se encarga de los datos y la lógica de negocio, View se encarga de la interfaz de usuario, Controller se encarga del procesamiento de entrada y la coordinación entre Model y View. En iOS, MVC se implementa a través de UIViewController, en Android — a través de Activity y Fragment. MVC sigue siendo el patrón fundamental sobre el cual se construyen MVVM, MVP y Clean Architecture. Más información en MVC in Cocoa Core.

Puntos clave

  • MVC — tres componentes: Model (datos), View (interfaz), Controller (lógica)
  • UIViewController — implementación de Controller en iOS, responsable del ciclo de vida de la pantalla
  • Activity/Fragment — implementación de Controller en Android con funciones similares
  • Massive View Controller — principal problema de MVC: el controlador crece hasta miles de líneas
  • Comunicación de componentes — Controller actualiza View y Model, Model notifica a Controller de los cambios

¿Qué es MVC?: la esencia del patrón Model-View-Controller

MVC (Model-View-Controller) es un patrón arquitectónico propuesto por Trygve Reenskaug en 1979 para el lenguaje Smalltalk-80. El patrón divide una aplicación en tres capas: Model contiene datos y lógica de negocio, View se encarga de la visualización, Controller procesa la entrada del usuario y actualiza Model y View. La separación de responsabilidades permite cambiar cada capa de forma independiente — por ejemplo, reemplazar View de UIKit a SwiftUI sin cambiar la lógica de negocio en Model.

Interacción de componentes en MVC sigue un ciclo: el usuario interactúa con View → Controller recibe el evento → Controller actualiza Model → Model notifica a Controller de los cambios → Controller actualiza View. En la implementación clásica, Model usa el patrón Observer: cuando los datos cambian, Model envía notificaciones, Controller se suscribe y actualiza View. En la implementación de Apple, Key-Value Observing (KVO) o NotificationCenter realizan esta función.

ComponenteResponsabilidadEjemplo en iOSEjemplo en Android
ModelDatos, lógica de negocio, redStruct User, CoreDataData class, Repository
ViewVisualización de UIStoryboard, XIB, UIViewXML layout, Jetpack Compose
ControllerProcesamiento de entrada, coordinaciónUIViewControllerActivity, Fragment

MVC en el desarrollo móvil moderno se usa menos que hace 10 años, pero sigue siendo esencial de entender. Apple recomienda MVC para pantallas simples en aplicaciones UIKit. Google no recomienda MVC puro para Android — la documentación oficial sugiere MVVM con Jetpack. Sin embargo, el conocimiento de MVC es necesario para trabajar con proyectos heredados y para comprender la evolución de los patrones arquitectónicos.

MVC en iOS: UIViewController y Storyboard

Apple MVC es una implementación personalizada del patrón integrada en UIKit. UIViewController actúa como Controller: gestiona el ciclo de vida de la pantalla (viewDidLoad, viewWillAppear, viewDidDisappear), maneja toques y acciones del usuario, actualiza View a través de IBOutlets. View se crea en Interface Builder (storyboard o XIB) o programáticamente. Model — cualquier objeto de datos: servicios de red, pilas de CoreData, estructuras de Swift.

swift
final class UserViewController: UIViewController {
    // View (a través de storyboard outlet)
    @IBOutlet private var nameLabel: UILabel!
    @IBOutlet private var emailLabel: UILabel!

    // Model
    private let userService = UserService()

    override func viewDidLoad() {
        super.viewDidLoad()
        loadUser()
    }

    private func loadUser() {
        userService.fetchUser { [weak self] user in
            // Controller actualiza View
            self?.nameLabel.text = user.name
            self?.emailLabel.text = user.email
        }
    }
}

El problema de Apple MVC — View y Controller están fuertemente acoplados. UIViewController gestiona simultáneamente tanto View como la lógica. Storyboard almacena View en XML, pero el controlador tiene referencias directas a elementos UI a través de IBOutlets. Esto viola el principio de responsabilidad única: el controlador es responsable del ciclo de vida, delegados, datasource, target-action y animaciones. Como resultado, una pantalla estándar de una aplicación iOS contiene 200–500 líneas en el controlador.

Ciclo de vida de ViewController — Apple proporciona 6 métodos de ciclo de vida: loadView (creación manual de View), viewDidLoad (después de cargar View en memoria), viewWillAppear (antes de aparecer en pantalla), viewDidAppear (después de la animación), viewWillDisappear (antes de salir de la pantalla), viewDidDisappear (después de salir). Cada método es un lugar para colocar lógica en MVC. Usar estos métodos para lógica de negocio acelera el crecimiento del controlador.

MVC en Android: Activity, Fragment y XML Layout

Android MVC — Activity y Fragment actúan como Controller, los archivos XML layout como View, cualquier clase POJO con datos como Model. Activity gestiona el ciclo de vida de la pantalla: onCreate, onStart, onResume, onPause, onStop, onDestroy. Fragment es una subpantalla dentro de Activity con su propio ciclo de vida. View (XML) está separada de Controller y se carga mediante setContentView o LayoutInflater. Model — repositorios, bases de datos, llamadas de red.

kotlin
class UserActivity : AppCompatActivity() {
    // View a través de XML layout
    private lateinit var binding: ActivityUserBinding

    // Model
    private val userRepository = UserRepository()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityUserBinding.inflate(layoutInflater)
        setContentView(binding.root)
        loadUser()
    }

    private fun loadUser() {
        userRepository.getUser { user ->
            runOnUiThread {
                binding.nameText.text = user.name
                binding.emailText.text = user.email
            }
        }
    }
}

Android ViewBinding y DataBinding — herramientas modernas que reducen el acoplamiento entre Controller y View. ViewBinding genera una clase con referencias directas a Views desde XML, eliminando findViewById. DataBinding añade la capacidad de vincular datos a la UI en el marcado XML mediante @{user.name}. DataBinding es un paso hacia MVVM, ya que permite pasar datos de Model a View sin código en Activity. Google recomienda DataBinding para todos los proyectos nuevos.

Ciclo de vida de Android es más complejo que iOS: Activity puede ser destruida y recreada al rotar la pantalla, por falta de memoria o cambio de configuración. En MVC puro, el controlador (Activity) contiene lógica que se pierde al destruirse. Esto requiere guardar el estado mediante onSaveInstanceState o ViewModel de Jetpack, lo que va más allá del MVC puro y acerca la arquitectura a MVVM.

Massive View Controller y limitaciones de MVC

Massive View Controller es un término que describe el principal problema de MVC en el desarrollo móvil. El controlador en iOS y Android asume demasiadas responsabilidades: procesamiento de entrada, validación de datos, interacción de red, navegación, almacenamiento en caché, animaciones, gestión del ciclo de vida. Como resultado, el controlador crece hasta 500–2000 líneas de código, volviéndose difícil de leer, probar y mantener.

Causas de Massive View Controller — la arquitectura de UIKit y Android Framework fomenta colocar la lógica en el controlador. Llamadas de red, procesamiento de JSON, navegación — todo esto naturalmente va en Activity o UIViewController porque tienen acceso al ciclo de vida y la UI. El desarrollador debe extraer conscientemente la lógica en clases separadas (Service, Manager, Interactor), lo que requiere disciplina y comprensión de los principios arquitectónicos.

Problema de MVCDescripciónSolución
Alto acoplamientoController conoce View y ModelMVVM — ViewModel no conoce View
Complejidad de pruebasController depende de UIKit/AndroidExtraer lógica en servicios
Ciclo de vidaEl estado se pierde al rotarViewModel de Jetpack/SwiftUI
Falta de navegaciónController gestiona transicionesPatrón Coordinator, Router

Pruebas de MVC — Model se prueba de forma aislada con pruebas unitarias. Controller es difícil de probar debido a la dependencia de UIKit/UIFoundation. XCTest no permite crear UIViewController sin una ventana de vista. Para Android, ActivityTestRule y Robolectric resuelven parcialmente el problema, pero las pruebas son lentas. View normalmente no se prueba con pruebas unitarias — para la UI se usan pruebas de captura de pantalla y pruebas de UI (XCUITest, Espresso).

Cuándo MVC está justificado — pantallas simples con uno o dos elementos (pantalla de inicio de sesión, perfil, configuración). Prototipos y MVP para validación de hipótesis — MVC es más rápido de escribir sin capas adicionales. Proyectos con una base de código pequeña de hasta 10–15 pantallas. En proyectos complejos, MVC conduce a la acumulación de deuda técnica y requiere refactorización cada 6–12 meses.

Comparación de MVC con MVVM, MVP y Clean Architecture

MVC vs MVVM — la principal diferencia: en MVVM, el controlador se reemplaza por ViewModel, que no tiene referencia a View. Los datos se pasan a través de Observable (SwiftUI), LiveData/StateFlow (Android) o Combine/RxSwift. ViewModel se puede probar con pruebas unitarias sin dependencias de UI. Apple recomienda MVVM con SwiftUI desde 2019, Google — MVVM con LiveData/Flow como la arquitectura oficial de Android. MVVM requiere más código para la vinculación, pero mejora significativamente la capacidad de prueba.

MVC vs MVP — en MVP (Model-View-Presenter), Presenter es una capa comprobable que recibe View a través de una interfaz. A diferencia de MVC donde Controller gestiona directamente View a través de UIKit, Presenter no depende del framework — funciona a través de la abstracción ViewInterface. MVP fue popular en el desarrollo de Android antes de Jetpack y se usa en proyectos heredados. Presenter sobrevive a Activity y conserva el estado al rotar la pantalla.

MVC vs Clean Architecture — Clean Architecture añade capas: Use Cases (Interactors), Entities, Gateways y Repository. MVC permanece en la capa de Presentation, pero la lógica de negocio se traslada a la capa de Domain con Use Cases. Clean Architecture resuelve radicalmente el problema de Massive View Controller — Controller solo contiene llamadas a Use Cases y actualizaciones de View. La desventaja es un aumento significativo en la cantidad de clases y archivos, lo que se justifica para proyectos con 50+ pantallas.

swift
// MVC en iOS: Controller lo contiene todo
class OrderViewController: UIViewController {
    func placeOrder() {
        // Validación + red + actualización de UI
        guard Validation.isValid(total) else { return }
        NetworkService.shared.submit(order) { [weak self] result in
            self?.handleResult(result)
        }
    }
}

// MVVM: lógica en ViewModel
class OrderViewModel: ObservableObject {
    @Published var state: OrderState = .idle
    func placeOrder() { /* lógica de negocio */ }
}

Elección de arquitectura depende del tamaño del equipo, el alcance del proyecto y la capacidad de prueba requerida. Para un equipo de 1–2 desarrolladores y un proyecto de hasta 20 pantallas, MVVM funciona bien. Para un equipo grande de 5+ desarrolladores y un proyecto con 50+ pantallas — Clean Architecture con estructura modular. MVC sigue siendo relevante para comprender la evolución de las arquitecturas, mantener proyectos heredados y para pantallas simples de UIKit sin lógica de negocio compleja.

Preguntas frecuentes

¿Cuál es el principal problema de MVC en el desarrollo móvil?

El principal problema es Massive View Controller. En iOS, UIViewController maneja todo: procesamiento de entrada, actualización de View, redes, navegación y ciclo de vida. En Android, Activity/Fragment realiza funciones similares. Como resultado, el controlador crece hasta miles de líneas de código, volviéndose difícil de probar y mantener, violando el principio de responsabilidad única.

¿En qué se diferencia MVC de MVVM?

En MVC, el controlador actualiza directamente View y procesa la entrada del usuario. En MVVM, el rol de controlador lo realiza ViewModel, que no tiene referencia a View — los datos se pasan a través de mecanismos de enlace. MVVM es más fácil de probar porque ViewModel no depende de UIKit o Android Framework. Apple recomienda MVVM con SwiftUI, Google recomienda MVVM con Jetpack Compose.

¿Se puede usar MVC en proyectos modernos?

Sí, MVC sigue siendo un patrón funcional para pantallas simples y prototipos. Apple recomienda MVC para aplicaciones UIKit con pantallas simples. Para proyectos complejos con muchas pantallas, solicitudes de red y almacenamiento en caché, es mejor elegir MVVM, VIPER o Clean Architecture. Se recomienda a los desarrolladores principiantes dominar MVC antes de aprender patrones más complejos.

¿Cómo probar una aplicación MVC?

Model se prueba de forma aislada — son objetos de datos y lógica de negocio regulares. Controller es difícil de probar debido a la dependencia de UIKit o Android Framework. Se recomienda extraer la lógica de negocio del controlador en servicios o interactores separados, que se prueban con pruebas unitarias. View normalmente no se prueba con pruebas unitarias — se utilizan pruebas de UI y pruebas de captura de pantalla.

¿Qué patrón elegir después de MVC?

En iOS — MVVM con SwiftUI y Combine, el estándar de Apple desde 2019. En Android — MVVM con LiveData o StateFlow, oficialmente recomendado por Google. Para proyectos grandes con equipos de 5+ desarrolladores — Clean Architecture con VIPER en iOS o Clean Architecture en Android con separación de módulos por funcionalidad. Para proyectos heredados con MVC — refactorización gradual con extracción de lógica en servicios separados.

Resumen

  • MVC — patrón arquitectónico con separación en Model, View y Controller
  • iOS MVC — UIViewController + storyboard + servicios de datos
  • Android MVC — Activity/Fragment + XML layout + repositorios
  • Massive View Controller — principal problema por mezcla de responsabilidades
  • Pruebas — Model es fácil de probar, Controller requiere extraer lógica
  • Evolución — MVC → MVVM → Clean Architecture para proyectos en crecimiento
  • Compatibilidad — los patrones se pueden combinar en un mismo proyecto

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también