Sobes.tech
Middle

Cuéntame sobre el patrón MVVM (Model-View-ViewModel).

sobes.tech AI

Respuesta de la IA

MVC (Modelo-Vista-Controlador).

Componente Descripción Responsabilidad
Modelo Representa los datos y la lógica de negocio de la aplicación. No depende de la Vista ni del ViewModel. Gestión de datos, reglas de negocio, interacción con servidor/base de datos.
Vista Interfaz de usuario. Muestra datos y transmite acciones del usuario al ViewModel. No contiene lógica de procesamiento de datos. Mostrar información, manejar eventos del usuario (toques, deslizamientos, etc.).
ViewModel Intermediario entre Modelo y Vista. Proporciona a la Vista datos en un formato adecuado para mostrar y procesa acciones del usuario, interactuando con el Modelo. No sabe si la Vista está en uso o no, solo se comunica mediante enlace de datos. Transformar datos del Modelo para la Vista, manejar interacciones del usuario, lógica de negocio no relacionada con la UI.

Principios básicos:

  • Enlace de Datos: Vinculación de datos entre la Vista y el ViewModel. Cuando los datos en el ViewModel cambian, la Vista se actualiza automáticamente, y viceversa.
  • Prueba: El ViewModel es fácil de probar, ya que no depende del framework de UI.
  • Separación de Responsabilidades: División clara de roles de los componentes.

Ventajas:

  • Mejor capacidad de prueba.
  • División más limpia de responsabilidades.
  • Simplificación de la base de código al trabajar con UI compleja.

Desventajas:

  • Puede ser excesivo para aplicaciones simples.
  • Complejidad en la implementación del enlace de datos sin frameworks externos (por ejemplo, RxSwift, Combine).

Ejemplo de estructura:

// Modelo
struct User {
    let name: String
    let age: Int
}

// ViewModel
class UserViewModel {
    private let user: User

    init(user: User) {
        self.user = user
    }

    var displayName: String {
        return user.name
    }

    var displayAge: String {
        return "\(user.age) años"
    }

    // Método para manejar acciones del usuario
    func userTapped() {
        print("Usuario \(user.name) fue pulsado")
        // Posiblemente interactúa con el Modelo u otra lógica
    }
}

// Vista (UIViewController)
class UserViewController: UIViewController {

    private var viewModel: UserViewModel!

    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var ageLabel: UILabel!

    func configure(with viewModel: UserViewModel) {
        self.viewModel = viewModel
        updateUI()
    }

    private func updateUI() {
        // Enlace de datos (ejemplo de enlace manual)
        nameLabel.text = viewModel.displayName
        ageLabel.text = viewModel.displayAge
    }

    @IBAction func tapGestureRecognized(_ sender: Any) {
        viewModel.userTapped()
    }
}