Middle
Opowiedz o wzorcu MVVM (Model-View-ViewModel).
sobes.tech AI
Odpowiedź od AI
MVC (Model-Widok-Kontroler).
| Komponent | Opis | Odpowiedzialność |
|---|---|---|
| Model | Reprezentuje dane i logikę biznesową aplikacji. Nie zależy od Widoku ani ViewModelu. | Zarządzanie danymi, reguły biznesowe, interakcja z serwerem/bazą danych. |
| Widok | Interfejs użytkownika. Wyświetla dane i przekazuje działania użytkownika do ViewModelu. Nie zawiera logiki przetwarzania danych. | Wyświetlanie informacji, obsługa zdarzeń użytkownika (dotknięcia, przesunięcia itp.). |
| ViewModel | Pośrednik między Modelem a Widokiem. Dostarcza Widokowi dane w formacie odpowiednim do wyświetlenia i obsługuje działania użytkownika, współpracując z Modelem. Nie wie, czy Widok jest używany, komunikuje się tylko przez wiązanie danych. | Przekształcanie danych z Modelu dla Widoku, obsługa interakcji użytkownika, logika biznesowa niezwiązana z UI. |
Podstawowe zasady:
- Wiązanie danych: Powiązanie danych między Widokiem a ViewModel. Gdy dane w ViewModelu się zmieniają, Widok jest automatycznie aktualizowany i odwrotnie.
- Testowalność: ViewModel jest łatwy do przetestowania, ponieważ nie zależy od frameworka UI.
- Oddzielenie odpowiedzialności: Jasny podział ról komponentów.
Zalety:
- Lepsza testowalność.
- Czystszy podział odpowiedzialności.
- Uproszczenie bazy kodu przy pracy z rozbudowanym UI.
Wady:
- Może być zbędny dla prostych aplikacji.
- Złożoność implementacji wiązania danych bez zewnętrznych frameworków (np. RxSwift, Combine).
Przykład 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) lat"
}
// Metoda obsługi działań użytkownika
func userTapped() {
print("Użytkownik \(user.name) został naciśnięty")
// Może współpracować z Modelem lub inną logiką
}
}
// Widok (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() {
// Wiązanie danych (przykład ręcznego wiązania)
nameLabel.text = viewModel.displayName
ageLabel.text = viewModel.displayAge
}
@IBAction func tapGestureRecognized(_ sender: Any) {
viewModel.userTapped()
}
}