Πώς να επιλέξετε την κατάλληλη αρχιτεκτονική iOS (Μέρος 2)

MVC, MVP, MVVM, VIPER ή VIP

Μπορείτε να συμβουλευτείτε το πρώτο μέρος εδώ.

Οι βασικές αρχιτεκτονικές iOS

Μια σύντομη επισκόπηση.

MVC

Οι στρώσεις MVC έχουν ως εξής:

M: Επιχειρηματική Λογική, Επίπεδο Δικτύου και Επίπεδο Πρόσβασης Δεδομένων

V: Επίπεδο UI (πράγματα UIKit, Storyboards, Xibs)

C: Συντονίζει τη διαμεσολάβηση μεταξύ μοντέλου και προβολής.

Για να κατανοήσουμε τη MVC, πρέπει να κατανοήσουμε το πλαίσιο στο οποίο εφευρέθηκε. Το MVC επινοήθηκε στις παλιές ημέρες ανάπτυξης στο Web, όπου οι προβολές δεν έχουν κατάσταση. Στην παλιά εποχή κάθε φορά που χρειαζόμαστε μια οπτική αλλαγή στον ιστότοπο, ο browser ξαναφορτώνει ξανά ολόκληρο το HTML. Εκείνη την εποχή δεν υπήρχε καμία έννοια της διατήρησης και της εξοικονόμησης της κατάστασης.

Υπήρχαν, για παράδειγμα, μερικοί προγραμματιστές που αναμίχθηκαν μέσα στο ίδιο αρχείο HTML, PHP και πρόσβαση σε βάση δεδομένων. Έτσι, το κύριο κίνητρο της MVC ήταν να διαχωρίσει το επίπεδο προβολής από το επίπεδο μοντέλου. Αυτό αύξησε τη δυνατότητα δοκιμής του στρώματος μοντέλου. Προφανώς στο MVC, το στρώμα προβολής και μοντέλου δεν πρέπει να γνωρίζει τίποτε άλλο. Για να γίνει αυτό δυνατό, δημιουργήθηκε ένα ενδιάμεσο επίπεδο με την ονομασία Controller. Αυτό ήταν το SRP που εφαρμόστηκε.

Ένα παράδειγμα του κύκλου MVC:

  1. Μια ενέργεια / συμβάν χρήστη στο επίπεδο προβολής (π.χ.: Ανανέωση ενέργειας) ενεργοποιείται και η ενέργεια αυτή κοινοποιείται στον ελεγκτή
  2. Ο ελεγκτής που ζητά δεδομένα στο επίπεδο μοντέλου
  3. Μοντελοποιήστε τα δεδομένα επιστροφής στον ελεγκτή
  4. Ο ελεγκτής λέει για την προβολή της ενημέρωσης την κατάσταση του με τα νέα δεδομένα
  5. Προβολή ενημέρωσης της κατάστασής του

Apple MVC

Στο iOS, ο ελεγκτής προβολής είναι συνδεδεμένος με το UIKit και την προβολή του κύκλου ζωής, οπότε δεν είναι καθαρό MVC. Ωστόσο, στον ορισμό MVC, δεν υπάρχει τίποτα που να λέει ότι ο ελεγκτής δεν μπορεί να γνωρίζει την υλοποίηση συγκεκριμένης προβολής ή μοντέλου. Ο κύριος σκοπός του είναι να διαχωρίσει τις ευθύνες του στρώματος Μοντέλο από το επίπεδο προβολής ώστε να μπορέσουμε να το ξαναχρησιμοποιήσουμε και να δοκιμάσουμε μεμονωμένα το στρώμα Μοντέλο.

Το ViewController περιέχει την προβολή και κατέχει το μοντέλο. Το πρόβλημα είναι ότι γράψαμε τον κώδικα ελεγκτή καθώς και τον κώδικα προβολής στο ViewController.

Η MVC συχνά δημιουργεί το αποκαλούμενο πρόβλημα ελεγκτή μαζικής προβολής, αλλά αυτό συμβαίνει και γίνεται σοβαρό σε εφαρμογές με αρκετή πολυπλοκότητα.

Υπάρχουν μερικές μέθοδοι που ο προγραμματιστής μπορεί να χρησιμοποιήσει για να καταστήσει πιο εύκολη τη διαχείριση του ελεγκτή προβολής. Μερικά παραδείγματα:

  • Εξαγωγή της λογικής VC για άλλες κλάσεις, όπως η πηγή δεδομένων μεθόδων προβολής πίνακα και η ανάθεση για άλλα αρχεία χρησιμοποιώντας το μοτίβο σχεδιασμού εκπροσώπων.
  • Δημιουργήστε έναν πιο ξεχωριστό χωρισμό των ευθυνών με τη σύνθεση (π.χ. Διαχωρισμός του VC σε ελεγκτές προβολής παιδιών).
  • Χρησιμοποιήστε το σχέδιο σχεδιασμού του συντονιστή για να αφαιρέσετε την ευθύνη της εφαρμογής της λογικής πλοήγησης στο VC
  • Χρησιμοποιήστε μια κλάση περιτύλιξης DataPresenter που ενσωματώνει τη λογική και μετατρέπει το μοντέλο δεδομένων σε μια έξοδο δεδομένων που αντιπροσωπεύει τα δεδομένα που παρουσιάζονται στον τελικό χρήστη.

MVC vs MVP

Πώς μπορείτε να δείτε το διάγραμμα του MVP είναι πολύ παρόμοιο με το MVC

Το MVC ήταν ένα βήμα μπροστά, αλλά εξακολουθούσε να χαρακτηρίζεται από απουσία ή σιωπή για κάποια πράγματα.

Εν τω μεταξύ, ο Παγκόσμιος Ιστός αυξήθηκε και πολλά πράγματα στην κοινότητα των προγραμματιστών εξελίχθηκαν. Με παραδείγματα, οι προγραμματιστές άρχισαν να χρησιμοποιούν το Ajax και μόνο να φορτώνουν μέρη σελίδων αντί για ολόκληρη τη σελίδα HTML ταυτόχρονα.

Στην MVC νομίζω ότι δεν υπάρχει τίποτα που να δείχνει ότι ο ελεγκτής δεν θα πρέπει να γνωρίζει την συγκεκριμένη υλοποίηση της προβολής (απουσίας).

Το HTML ήταν μέρος του Layer View και πολλές περιπτώσεις ήταν χαζή ως fuck. Σε ορισμένες περιπτώσεις, λαμβάνει μόνο συμβάντα από το χρήστη και εμφανίζει το οπτικό περιεχόμενο του GUI.

Καθώς τμήματα των ιστοσελίδων άρχισαν να φορτώνονται σε τμήματα, αυτή η κατάτμηση οδήγησε στην κατεύθυνση της διατήρησης της κατάστασης View και μεγαλύτερη ανάγκη για διαχωρισμό ευθύνης παρουσίασης.

Η λογική παρουσίασης είναι η λογική που ελέγχει τον τρόπο εμφάνισης του UI και τον τρόπο αλληλεπίδρασης των στοιχείων UI. Ένα παράδειγμα είναι η λογική ελέγχου του πότε ένα δείκτης φόρτωσης πρέπει να αρχίσει να εμφανίζεται / ζωντανεύει και πότε πρέπει να σταματήσει να εμφανίζεται / ζωντανεύει.

Στα MVP και MVVM το Layer View θα πρέπει να είναι χαζή ως fuck χωρίς καμία λογική ή ευφυΐα σε αυτό, και στο iOS, ο View Controller θα πρέπει να είναι μέρος του View Layer. Το γεγονός ότι η προβολή είναι χαζή σημαίνει ότι ακόμη και η λογική παρουσίασης παραμένει εκτός του Layer προβολής.

Ένα από τα προβλήματα της MVC είναι ότι δεν είναι σαφές για το πού πρέπει να παραμείνει η λογική παρουσίασης. Είναι απλά σιωπηλός γι 'αυτό. Πρέπει η λογική παρουσίασης να βρίσκεται στο επίπεδο προβολής ή στο επίπεδο μοντέλου;

Εάν ο ρόλος του μοντέλου είναι να παράσχει απλώς τα "ακατέργαστα" δεδομένα, σημαίνει ότι ο κώδικας στην προβολή θα είναι:

Εξετάστε το ακόλουθο παράδειγμα: έχουμε έναν χρήστη, με όνομα και επώνυμο. Στην προβολή, πρέπει να εμφανίσετε το όνομα χρήστη ως "όνομα, όνομα" (π.χ. "Flores, Tiago").

Εάν ο ρόλος του μοντέλου είναι να παράσχει τα "ακατέργαστα" δεδομένα, σημαίνει ότι ο κώδικας στην προβολή θα είναι:

let firstName = userModel.getFirstName ()
let lastName = userModel.getLastName ()
όνομαLabel.text = τελευταίαName + "," + firstName

Αυτό σημαίνει ότι θα ήταν ευθύνη της View να χειρίζεται τη λογική του UI. Αλλά αυτό καθιστά αδύνατη τη λογική της διεπαφής χρήστη UI.

Η άλλη προσέγγιση είναι το μοντέλο να εκθέτει μόνο τα δεδομένα που πρέπει να εμφανίζονται, αποκρύπτοντας οποιαδήποτε επιχειρησιακή λογική από την Προβολή. Αλλά τότε καταλήγουμε σε Μοντέλα που χειρίζονται τόσο τη λογική της επιχείρησης όσο και της UI. Θα ήταν μονάδα δοκιμής, αλλά τότε το μοντέλο καταλήγει, εξαρτώντας σιωπηρά από την Προβολή.

let name = userModel.getDisplayName ()
όνομαLabel.text = όνομα

Το MVP είναι σαφές γι 'αυτό και η λογική παρουσίασης παραμένει στο Layer Presenter. Αυτό αυξάνει τη δυνατότητα δοκιμής του στρώματος Presenter. Τώρα το Layer Model και Presenter Layer είναι εύκολο να ελεγχθεί.

Κανονικά στις υλοποιήσεις του MVP, η προβολή είναι κρυμμένη πίσω από μια διεπαφή / πρωτόκολλο και δεν πρέπει να υπάρχουν αναφορές στο UIKit στον παρουσιαστή.

Ένα άλλο πράγμα που πρέπει να έχουμε κατά νου είναι οι μεταβατικές εξαρτήσεις.

Εάν ο ελεγκτής έχει Business Layer ως εξάρτηση και το Business Layer έχει Data Access Layer ως εξάρτηση, τότε ο ελεγκτής έχει μια μεταβατική εξάρτηση για το Layer Access Data. Δεδομένου ότι οι εφαρμογές MVP συνήθως χρησιμοποιούν μια σύμβαση (πρωτόκολλο) μεταξύ όλων των επιπέδων δεν έχει μεταβατικές εξαρτήσεις.

Τα διαφορετικά στρώματα αλλάζουν επίσης για διάφορους λόγους και με διαφορετικούς ρυθμούς. Έτσι, όταν αλλάζετε ένα στρώμα, δεν θέλετε αυτό να προκαλεί δευτερεύοντα εφέ / προβλήματα στα άλλα στρώματα.

Τα πρωτόκολλα είναι πιο σταθερά από τις κατηγορίες. Τα πρωτόκολλα δεν έχουν λεπτομέρειες εφαρμογής και με τις συμβάσεις, επομένως είναι δυνατή η αλλαγή των λεπτομερειών εφαρμογής ενός στρώματος χωρίς να επηρεαστούν τα άλλα επίπεδα.

Επομένως, τα συμβόλαια (πρωτόκολλα) δημιουργούν μια αποσύνδεση μεταξύ των επιπέδων.

MVP έναντι MVVM

Διάγραμμα MVVM

Μία από τις κύριες διαφορές μεταξύ του MVP και του MVVM είναι ότι στο MVP ο Παρουσιαστής επικοινωνεί με τις διασυνδέσεις Προβολή και στο MVVM η Προβολή είναι προσανατολισμένη σε αλλαγές δεδομένων και γεγονότων.

Στο The MVP κάνουμε χειροκίνητη σύνδεση μεταξύ Presenter και View χρησιμοποιώντας διασυνδέσεις / πρωτόκολλα.
Στο MVVM κάνουμε την αυτόματη σύνδεση δεδομένων χρησιμοποιώντας κάτι σαν RxSwift, KVO ή χρησιμοποιώντας ένα μηχανισμό με γενικά και κλεισίματα.

Στο MVVM δεν χρειαζόμαστε ακόμη συμβόλαιο (π.χ.: interface java / πρωτόκολλο iOS) μεταξύ του ViewModel και του View, επειδή συνήθως επικοινωνούμε μέσω του Pattern Design Observer.

Το MVP χρησιμοποιεί το Delegate Pattern επειδή το Layer Presenter μεταβιβάζει εντολές στο Layer View, οπότε πρέπει να γνωρίζει κάτι για την προβολή ακόμα και αν είναι μόνο η υπογραφή διεπαφής / πρωτοκόλλου. Σκεφτείτε τη διαφορά μεταξύ του Κέντρου ειδοποιήσεων και των εκπροσώπων του TableView. Το Κέντρο Ειδοποίησης δεν χρειάζεται διεπαφές για τη δημιουργία καναλιού επικοινωνίας, αλλά οι εκπρόσωποι του TableView χρησιμοποιούν ένα πρωτόκολλο το οποίο πρέπει να εφαρμόσουν οι κλάσεις.

Σκεφτείτε τη λογική παρουσίασης ενός δείκτη φόρτωσης. Στο MVP ο παρουσιαστής κάνει το ViewProtocol.showLoadingIndicator. Στο MVVM μπορεί να υπάρχει μια ιδιότητα isLoading στο ViewModel. Το επίπεδο προβολής μέσω αυτόματης σύνδεσης δεδομένων ανιχνεύει πότε αυτή η ιδιότητα αλλάζει και ανανεώνεται. Το MVP είναι πιο επιτακτικό από το MVVM, επειδή ο Παρουσιαστής δίνει εντολές.

Το MVVM αφορά περισσότερο τις αλλαγές δεδομένων από τις άμεσες παραγγελίες και συνδέουμε τις αλλαγές δεδομένων με τις ενημερώσεις προβολών. Εάν χρησιμοποιήσουμε το RxSwift και το λειτουργικό αντιδραστικό προγραμματιστικό πρότυπο μαζί με το MVVM, έχουμε κάνει τον κώδικα ακόμα λιγότερο επιτακτικό και περισσότερο δηλωτικό.

Το MVVM είναι πιο εύκολο να δοκιμαστεί από το MVP, επειδή το MVVM χρησιμοποιεί το Pattern Design Observer που μεταφέρει δεδομένα μεταξύ των στοιχείων με αποσυνδεδεμένο τρόπο.
Έτσι μπορούμε να δοκιμάζουμε μόνο κοιτάζοντας τις αλλαγές στα δεδομένα μόνο συγκρίνοντας τα δύο αντικείμενα παρά δημιουργώντας ψεύτικες μεθόδους που καλούν τις μεθόδους για να ελέγξουν την επικοινωνία μεταξύ View and Presenter.

PS: Έκανα κάποιες ενημερώσεις για το άρθρο που την έκανε να μεγαλώσει πολύ, γι 'αυτό ήταν απαραίτητο να χωριστεί σε τρία μέρη. Μπορείτε να διαβάσετε το τρίτο μέρος εδώ.

Το δεύτερο μέρος τελειώνει εδώ. Όλα τα σχόλια είναι ευπρόσδεκτα. Στο τρίτο μέρος θα μιλήσουμε για VIPER, VIP, ενεργό προγραμματισμό, εμπόριο, περιορισμοί και συμφραζόμενα.

Ευχαριστούμε που το διαβάσατε! Εάν σας άρεσε αυτό το άρθρο, παρακαλώ χτυπάτε
έτσι άλλοι άνθρωποι μπορούν να το διαβάσουν και εγώ :)