Sobes.tech
Middle

Räägi mulle MVVM-mustrist (Model-View-ViewModel).

sobes.tech AI

Vastus AI-lt

MVC (Model-View-Controller).

Komponent Kirjeldus Vastutus
Model Esindab andmeid ja äriloogikat rakenduses. Ei sõltu View-st või ViewModel-st. Andmete haldamine, ärireeglid, suhtlus serveri/andmebaasiga.
View Kasutajaliides. Kuvab andmeid ja edastab kasutaja tegevused ViewModel-ile. Ei sisalda andmetöötluslogikat. Teabe kuvamine, kasutaja sündmuste töötlemine (puudutused, pihustused jne).
ViewModel vahend Model-i ja View-i vahel. Pakub View-le andmeid sobivas vormingus ja töötleb kasutaja tegevusi, suhtledes Model-iga. Ei tea, kas View-d kasutatakse või mitte, suhtleb ainult andme bindingu kaudu. Andmete teisendamine Model-ist View-ks, kasutaja interaktsioonide töötlemine, äriloogika, mis ei ole seotud UI-ga.

Põhiprintsiibid:

  • Data Binding: Andmete sidumine View ja ViewModel vahel. Kui andmed muutuvad ViewModel-is, uuendatakse View automaatselt, ja vastupidi.
  • Testability: ViewModel on lihtne testida, kuna see ei sõltu UI raamistikust.
  • Separation of Concerns: Komponentide rollide selge jaotus.

Eelised:

  • Paranenud testitavus.
  • Puhasuma vastutuse jaotuse.
  • Koodibaasi lihtsustamine keerukate UI-dega töötamisel.

Puudused:

  • Võib olla liigset lihtsate rakenduste jaoks.
  • Data Binding-i rakendamine ilma väliste raamistiketa (nt RxSwift, Combine) on keeruline.

Näidistruktuur:

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

    // Meetod kasutaja tegevuse töötlemiseks
    func userTapped() {
        print("Kasutaja \(user.name) vajutas")
        // Võimalik suhtlus Model-iga või muu loogikaga
    }
}

// Vaade (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() {
        // Andmete sidumine (näide käsitsi)
        nameLabel.text = viewModel.displayName
        ageLabel.text = viewModel.displayAge
    }

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