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