Sobes.tech
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()
    }
}