Sobes.tech
Middle

Πες μου για το μοτίβο MVVM (Model-View-ViewModel).

sobes.tech AI

Απάντηση από AI

MVC (Μοντέλο-Προβολή-Ελεγκτής).

Συστατικό Περιγραφή Ευθύνη
Μοντέλο Αντιπροσωπεύει τα δεδομένα και τη λογική επιχειρήσεων της εφαρμογής. Δεν εξαρτάται από το View ή το ViewModel. Διαχείριση δεδομένων, επιχειρηματικοί κανόνες, αλληλεπίδραση με διακομιστή/βάση δεδομένων.
Προβολή Διεπαφή χρήστη. Εμφανίζει δεδομένα και μεταφέρει ενέργειες χρήστη στο ViewModel. Δεν περιέχει λογική επεξεργασίας δεδομένων. Εμφάνιση πληροφοριών, διαχείριση συμβάντων χρήστη (αγγίγματα, σάρωση κ.λπ.).
ViewModel Μεσολαβητής μεταξύ Μοντέλου και Προβολής. Παρέχει στο View δεδομένα σε κατάλληλη μορφή και επεξεργάζεται ενέργειες χρήστη, αλληλεπιδρώντας με το Μοντέλο. Δεν γνωρίζει αν το View χρησιμοποιείται ή όχι, επικοινωνεί μόνο μέσω data binding. Μετατροπή δεδομένων από το Μοντέλο για το View, διαχείριση αλληλεπιδράσεων χρήστη, λογική επιχειρήσεων που δεν σχετίζεται με το UI.

Βασικές αρχές:

  • Data Binding: Δέσιμο δεδομένων μεταξύ View και ViewModel. Όταν αλλάζουν τα δεδομένα στο ViewModel, το View ενημερώνεται αυτόματα και το αντίστροφο.
  • Testability: Το ViewModel είναι εύκολο στον έλεγχο, καθώς δεν εξαρτάται από το πλαίσιο UI.
  • Διαχωρισμός ευθυνών: Ξεκάθαρος διαχωρισμός ρόλων των συστατικών.

Πλεονεκτήματα:

  • Βελτιωμένη δοκιμαστικότητα.
  • Καθαρότερος διαχωρισμός ευθυνών.
  • Απλοποίηση της βάσης κώδικα κατά την εργασία με πολύπλοκα UI.

Μειονεκτήματα:

  • Μπορεί να είναι περιττό για απλές εφαρμογές.
  • Πολυπλοκότητα στην υλοποίηση data binding χωρίς εξωτερικά frameworks (π.χ., RxSwift, Combine).

Παραδείγματα δομής:

// Μοντέλο
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) ετών"
    }

    // Μέθοδος για επεξεργασία ενεργειών χρήστη
    func userTapped() {
        print("Ο χρήστης \(user.name) πατήθηκε")
        // Πιθανώς αλληλεπιδρά με το Μοντέλο ή άλλη λογική
    }
}

// Προβολή (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 (παραδείγμα χειροκίνητης σύνδεσης)
        nameLabel.text = viewModel.displayName
        ageLabel.text = viewModel.displayAge
    }

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