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()
}
}