Sobes.tech
Middle

Porozprávaj mi o vzorec MVVM (Model-View-ViewModel).

sobes.tech AI

Odpoveď od AI

MVC (Model-View-Controller).

Zložka Popis Zodpovednosť
Model Predstavuje údaje a podnikateľskú logiku aplikácie. Nezávisí od View alebo ViewModel. Riadenie údajov, podnikateľské pravidlá, interakcia so serverom/databázou.
View Používateľské rozhranie. Zobrazuje údaje a odovzdáva akcie používateľa ViewModelu. Neobsahuje logiku spracovania údajov. Zobrazenie informácií, spracovanie udalostí používateľa (tapnutia, swipy atď.).
ViewModel Prostredník medzi Modelom a View. Poskytuje View údaje v vhodnom formáte na zobrazenie a spracováva akcie používateľa, komunikujúc s Modelom. Nevie, či sa View používa alebo nie, komunikuje iba cez data binding. Prevod údajov z Modelu do View, spracovanie interakcií používateľa, podnikateľská logika, ktorá nesúvisí s UI.

Hlavné princípy:

  • Data Binding: Prepojenie údajov medzi View a ViewModel. Pri zmene údajov vo ViewModel sa View automaticky aktualizuje, a naopak.
  • Testovateľnosť: ViewModel je ľahko testovateľný, pretože nezávisí od UI frameworku.
  • Oddelenie zodpovedností: Jasné rozdelenie rolí komponentov.

Výhody:

  • Zlepšená testovateľnosť.
  • Čistejšie rozdelenie zodpovedností.
  • Zjednodušenie kódovej základne pri práci s komplexným UI.

Nevýhody:

  • Môže byť nadbytočný pre jednoduché aplikácie.
  • Zložitosť implementácie Data Binding bez externých frameworkov (napr. RxSwift, Combine).

Príklad štruktúry:

// Model
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) rokov"
    }

    // Metóda na spracovanie akcií používateľa
    func userTapped() {
        print("Používateľ \(user.name) bol stlačený")
        // Možná interakcia s Modelom alebo inou logikou
    }
}

// View (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() {
        // Data Binding (príklad ručného prepojenia)
        nameLabel.text = viewModel.displayName
        ageLabel.text = viewModel.displayAge
    }

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