Sobes.tech
Middle

Pověz mi o vzoru MVVM (Model-View-ViewModel).

sobes.tech AI

Odpověď od AI

MVC (Model-View-Controller).

Komponenta Popis Odpovědnost
Model Představuje data a obchodní logiku aplikace. Nezávisí na View nebo ViewModel. Správa dat, obchodní pravidla, komunikace se serverem/databází.
View Uživatelské rozhraní. Zobrazuje data a předává akce uživatele ViewModelu. Neobsahuje logiku zpracování dat. Zobrazení informací, správa událostí uživatele (tapy, posuny atd.).
ViewModel Prostředník mezi Modelem a View. Poskytuje View data ve vhodném formátu a zpracovává akce uživatele, spolupracuje s Modelem. Neví, jestli je View používáno nebo ne, komunikuje pouze přes datové vazby. Převod dat z Modelu pro View, zpracování uživatelských interakcí, obchodní logika nesouvisející s UI.

Základní principy:

  • Data Binding: Vazba dat mezi View a ViewModel. Při změně dat ve ViewModelu se View automaticky aktualizuje, a naopak.
  • Testovatelnost: ViewModel je snadno testovatelný, protože nezávisí na UI frameworku.
  • Oddělení odpovědností: Jasné rozdělení rolí komponent.

Výhody:

  • Zlepšená testovatelnost.
  • Čistší rozdělení odpovědností.
  • Zjednodušení kódové základny při práci s komplexním UI.

Nevýhody:

  • Může být nadbytečný pro jednoduché aplikace.
  • Složitost implementace Data Binding bez externích frameworků (například RxSwift, Combine).

Příklad struktury:

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

    // Metoda pro zpracování akcí uživatele
    func userTapped() {
        print("Uživatel \(user.name) byl stisknut")
        // Může komunikovat s Modelem nebo jinou 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 (příklad ruční vazby)
        nameLabel.text = viewModel.displayName
        ageLabel.text = viewModel.displayAge
    }

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