MVC (Model-View-Controller) — ένα αρχιτεκτονικό πρότυπο που χωρίζει την εφαρμογή σε τρία στοιχεία: το Model είναι υπεύθυνο για τα δεδομένα και την επιχειρηματική λογική, το View — για τη διεπαφή χρήστη, ο Controller — για την επεξεργασία εισόδου και τον συντονισμό Model και View. Στο iOS, το MVC υλοποιείται μέσω του UIViewController, στο Android — μέσω των Activity και Fragment. Το MVC παραμένει το βασικό πρότυπο πάνω στο οποίο βασίζονται τα MVVM, MVP και Clean Architecture. Περισσότερα — στο MVC in Cocoa Core.
Κύρια σημεία
MVC (Model-View-Controller) — ένα αρχιτεκτονικό πρότυπο που προτάθηκε από τον Trygve Reenskaug το 1979 για τη γλώσσα Smalltalk-80. Το πρότυπο χωρίζει την εφαρμογή σε τρία επίπεδα: το Model περιέχει δεδομένα και επιχειρηματική λογική, το View είναι υπεύθυνο για την προβολή, ο Controller επεξεργάζεται την είσοδο χρήστη και ενημερώνει το Model και το View. Ο διαχωρισμός ευθυνών επιτρέπει την ανεξάρτητη τροποποίηση κάθε επιπέδου — για παράδειγμα, αντικατάσταση του View από UIKit σε SwiftUI χωρίς αλλαγή της επιχειρηματικής λογικής στο Model.
Αλληλεπίδραση στοιχείων στο MVC ακολουθεί έναν κύκλο: ο χρήστης αλληλεπιδρά με το View → ο Controller λαμβάνει το συμβάν → ο Controller ενημερώνει το Model → το Model ειδοποιεί τον Controller για αλλαγές → ο Controller ενημερώνει το View. Στην κλασική υλοποίηση, το Model χρησιμοποιεί το πρότυπο Observer: όταν αλλάζουν τα δεδομένα, το Model στέλνει ειδοποιήσεις, ο Controller εγγράφεται και ενημερώνει το View. Στην υλοποίηση της Apple, το Key-Value Observing (KVO) ή το NotificationCenter εκτελούν αυτόν τον ρόλο.
| Στοιχείο | Ευθύνη | Παράδειγμα στο iOS | Παράδειγμα στο Android |
|---|---|---|---|
| Model | Δεδομένα, επιχειρηματική λογική, δίκτυο | Struct User, CoreData | Data class, Repository |
| View | Προβολή UI | Storyboard, XIB, UIView | Διάταξη XML, Jetpack Compose |
| Controller | Επεξεργασία εισόδου, συντονισμός | UIViewController | Activity, Fragment |
MVC στη σύγχρονη ανάπτυξη κινητών χρησιμοποιείται λιγότερο από ό,τι πριν από 10 χρόνια, αλλά παραμένει υποχρεωτικό για κατανόηση. Η Apple συνιστά MVC για απλές οθόνες σε εφαρμογές UIKit. Η Google δεν συνιστά καθαρό MVC για Android — η επίσημη τεκμηρίωση προτείνει MVVM με Jetpack. Ωστόσο, η γνώση του MVC είναι απαραίτητη για εργασία με κληρονομικά έργα και για κατανόηση της εξέλιξης των αρχιτεκτονικών προτύπων.
Apple MVC — μια προσαρμοσμένη υλοποίηση του προτύπου ενσωματωμένη στο UIKit. Ο UIViewController εκτελεί τον ρόλο του Controller: διαχειρίζεται τον κύκλο ζωής της οθόνης (viewDidLoad, viewWillAppear, viewDidDisappear), επεξεργάζεται αγγίγματα και ενέργειες χρήστη, ενημερώνει το View μέσω IBOutlets. Το View δημιουργείται στο Interface Builder (storyboard ή XIB) ή προγραμματιστικά. Model — οποιαδήποτε αντικείμενα δεδομένων: υπηρεσίες δικτύου, στοίβες CoreData, δομές Swift.
final class UserViewController: UIViewController {
// View (μέσω storyboard outlet)
@IBOutlet private var nameLabel: UILabel!
@IBOutlet private var emailLabel: UILabel!
// Model
private let userService = UserService()
override func viewDidLoad() {
super.viewDidLoad()
loadUser()
}
private func loadUser() {
userService.fetchUser { [weak self] user in
// Ο Controller ενημερώνει το View
self?.nameLabel.text = user.name
self?.emailLabel.text = user.email
}
}
}
Πρόβλημα του Apple MVC — το View και ο Controller είναι στενά συνδεδεμένα. Ο UIViewController διαχειρίζεται ταυτόχρονα τόσο το View όσο και τη λογική. Το Storyboard αποθηκεύει το View σε XML, αλλά ο ελεγκτής έχει άμεσες αναφορές σε στοιχεία UI μέσω IBOutlets. Αυτό παραβιάζει την αρχή της μοναδικής ευθύνης: ο ελεγκτής είναι υπεύθυνος για τον κύκλο ζωής, τους εκπροσώπους, το datasource, το target-action και τις κινούμενες εικόνες. Ως αποτέλεσμα, μια τυπική οθόνη εφαρμογής iOS περιέχει 200–500 γραμμές στον ελεγκτή.
Κύκλος ζωής ViewController — η Apple παρέχει 6 μεθόδους κύκλου ζωής: loadView (μη αυτόματη δημιουργία View), viewDidLoad (μετά τη φόρτωση View στη μνήμη), viewWillAppear (πριν από την εμφάνιση στην οθόνη), viewDidAppear (μετά την κινούμενη εικόνα), viewWillDisappear (πριν από την αποχώρηση από την οθόνη), viewDidDisappear (μετά την αποχώρηση). Κάθε μέθοδος — ένα μέρος για τοποθέτηση λογικής στο MVC. Η χρήση αυτών των μεθόδων για επιχειρηματική λογική επιταχύνει την ανάπτυξη του ελεγκτή.
Android MVC — τα Activity και Fragment εκτελούν τον ρόλο του Controller, τα αρχεία διάταξης XML — View, οποιαδήποτε κλάση POJO με δεδομένα — Model. Το Activity διαχειρίζεται τον κύκλο ζωής της οθόνης: onCreate, onStart, onResume, onPause, onStop, onDestroy. Fragment — υπο-οθόνη εντός του Activity με δικό της κύκλο ζωής. Το View (XML) είναι ξεχωριστό από τον Controller και φορτώνεται μέσω setContentView ή LayoutInflater. Model — αποθετήρια, βάσεις δεδομένων, κλήσεις δικτύου.
class UserActivity : AppCompatActivity() {
// View μέσω διάταξης XML
private lateinit var binding: ActivityUserBinding
// Model
private val userRepository = UserRepository()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityUserBinding.inflate(layoutInflater)
setContentView(binding.root)
loadUser()
}
private fun loadUser() {
userRepository.getUser { user ->
runOnUiThread {
binding.nameText.text = user.name
binding.emailText.text = user.email
}
}
}
}
Android ViewBinding και DataBinding — σύγχρονα εργαλεία που μειώνουν τη σύζευξη Controller και View. Το ViewBinding δημιουργεί μια κλάση με άμεσες αναφορές στο View από XML, εξαλείφοντας το findViewById. Το DataBinding προσθέτει τη δυνατότητα σύνδεσης δεδομένων με το UI σε σήμανση XML μέσω @{user.name}. Το DataBinding — ένα βήμα προς το MVVM, καθώς επιτρέπει τη μεταφορά δεδομένων από το Model στο View χωρίς κώδικα στο Activity. Η Google συνιστά το DataBinding για όλα τα νέα έργα.
Ο κύκλος ζωής Android είναι πιο περίπλοκος από το iOS: το Activity μπορεί να καταστραφεί και να αναδημιουργηθεί κατά την περιστροφή της οθόνης, έλλειψη μνήμης ή αλλαγή διαμόρφωσης. Στο καθαρό MVC, ο ελεγκτής (Activity) περιέχει λογική που χάνεται κατά την καταστροφή. Αυτό απαιτεί αποθήκευση κατάστασης μέσω onSaveInstanceState ή ViewModel από το Jetpack, το οποίο υπερβαίνει το πλαίσιο του καθαρού MVC και φέρνει την αρχιτεκτονική πιο κοντά στο MVVM.
Massive View Controller — ένας όρος που περιγράφει το κύριο πρόβλημα του MVC στην ανάπτυξη κινητών. Ο ελεγκτής στο iOS και το Android αναλαμβάνει πάρα πολλές ευθύνες: επεξεργασία εισόδου, επικύρωση δεδομένων, αλληλεπίδραση δικτύου, πλοήγηση, προσωρινή αποθήκευση, κινούμενες εικόνες, διαχείριση κύκλου ζωής. Ως αποτέλεσμα, ο ελεγκτής μεγαλώνει σε 500–2000 γραμμές κώδικα, γίνεται δύσκολος στην ανάγνωση, δοκιμή και συντήρηση.
Αιτίες του Massive View Controller — η αρχιτεκτονική του UIKit και του Android Framework ενθαρρύνει την τοποθέτηση λογικής στον ελεγκτή. Κλήσεις δικτύου, επεξεργασία JSON, πλοήγηση — όλα αυτά γράφονται φυσικά στο Activity ή το UIViewController, επειδή έχουν πρόσβαση στον κύκλο ζωής και το UI. Ο προγραμματιστής πρέπει συνειδητά να μεταφέρει τη λογική σε ξεχωριστές κλάσεις (Service, Manager, Interactor), το οποίο απαιτεί πειθαρχία και κατανόηση αρχιτεκτονικών αρχών.
| Πρόβλημα MVC | Περιγραφή | Λύση |
|---|---|---|
| Ισχυρή σύζευξη | Ο Controller γνωρίζει το View και το Model | MVVM — το ViewModel δεν γνωρίζει το View |
| Δυσκολία δοκιμής | Ο Controller εξαρτάται από UIKit/Android | Μεταφορά λογικής σε υπηρεσίες |
| Κύκλος ζωής | Η κατάσταση χάνεται κατά την περιστροφή | ViewModel από Jetpack/SwiftUI |
| Έλλειψη πλοήγησης | Ο Controller διαχειρίζεται μεταβάσεις | Πρότυπο Coordinator, Router |
Δοκιμή MVC — το Model δοκιμάζεται απομονωμένα με μοναδιαίες δοκιμές. Ο Controller είναι δύσκολο να δοκιμαστεί λόγω εξάρτησης από UIKit/UIFoundation. Το XCTest δεν επιτρέπει τη δημιουργία UIViewController χωρίς παράθυρο προβολής. Για Android, τα ActivityTestRule και Robolectric λύνουν εν μέρει το πρόβλημα, αλλά οι δοκιμές είναι αργές. Το View συνήθως δεν δοκιμάζεται με μοναδιαίες δοκιμές — για το UI χρησιμοποιούνται δοκιμές στιγμιότυπων οθόνης και UI (XCUITest, Espresso).
Πότε το MVC είναι δικαιολογημένο — απλές οθόνες με ένα-δύο στοιχεία (οθόνη σύνδεσης, προφίλ, ρυθμίσεις). Πρωτότυπα και MVP για δοκιμή υποθέσεων — το MVC γράφεται ταχύτερα χωρίς πρόσθετα επίπεδα. Έργα με μικρή βάση κώδικα έως 10–15 οθόνες. Σε σύνθετα έργα, το MVC οδηγεί σε συσσώρευση τεχνικού χρέους και απαιτεί αναδόμηση κάθε 6–12 μήνες.
MVC vs MVVM — η κύρια διαφορά: στο MVVM ο ελεγκτής αντικαθίσταται από το ViewModel, το οποίο δεν έχει αναφορά στο View. Τα δεδομένα μεταφέρονται μέσω Observable (SwiftUI), LiveData/StateFlow (Android) ή Combine/RxSwift. Το ViewModel δοκιμάζεται με μοναδιαίες δοκιμές χωρίς εξαρτήσεις UI. Η Apple συνιστά MVVM με SwiftUI από το 2019, η Google — MVVM με LiveData/Flow ως επίσημη αρχιτεκτονική Android. Το MVVM απαιτεί περισσότερο κώδικα για σύνδεση, αλλά βελτιώνει σημαντικά τη δυνατότητα δοκιμής.
MVC vs MVP — στο MVP (Model-View-Presenter) ο Presenter είναι ένα δοκιμάσιμο επίπεδο που λαμβάνει το View μέσω διεπαφής. Σε αντίθεση με το MVC, όπου ο Controller διαχειρίζεται άμεσα το View μέσω UIKit, ο Presenter δεν εξαρτάται από το πλαίσιο — λειτουργεί μέσω της αφαίρεσης ViewInterface. Το MVP ήταν δημοφιλές στην ανάπτυξη Android πριν από την εμφάνιση του Jetpack και χρησιμοποιείται σε παλιά έργα. Ο Presenter ζει περισσότερο από το Activity και διατηρεί την κατάσταση κατά την περιστροφή της οθόνης.
MVC vs Clean Architecture — η Clean Architecture προσθέτει επίπεδα Use Cases (Interactors), Entities, Gateways και Repository. Το MVC παραμένει στο επίπεδο Presentation, αλλά η επιχειρηματική λογική μεταφέρεται στο επίπεδο Domain με Use Cases. Η Clean Architecture λύνει το πρόβλημα του Massive View Controller ριζικά — ο Controller περιέχει μόνο κλήσεις Use Cases και ενημέρωση του View. Μειονέκτημα — σημαντική αύξηση του αριθμού κλάσεων και αρχείων, το οποίο δικαιολογείται για έργα με 50+ οθόνες.
// MVC στο iOS: Ο Controller περιέχει τα πάντα
class OrderViewController: UIViewController {
func placeOrder() {
// Επικύρωση + δίκτυο + ενημέρωση UI
guard Validation.isValid(total) else { return }
NetworkService.shared.submit(order) { [weak self] result in
self?.handleResult(result)
}
}
}
// MVVM: λογική στο ViewModel
class OrderViewModel: ObservableObject {
@Published var state: OrderState = .idle
func placeOrder() { /* επιχειρηματική λογική */ }
}
Επιλογή αρχιτεκτονικής εξαρτάται από το μέγεθος της ομάδας, το έργο και την απαιτούμενη δυνατότητα δοκιμής. Για ομάδα 1–2 προγραμματιστών και έργο έως 20 οθόνες, το MVVM είναι κατάλληλο. Για μεγάλη ομάδα από 5 προγραμματιστές και έργο από 50 οθόνες — Clean Architecture με αρθρωτή δομή. Το MVC παραμένει επίκαιρο για την κατανόηση της εξέλιξης των αρχιτεκτονικών, για υποστήριξη κληρονομικών έργων και για απλές οθόνες στο UIKit χωρίς σύνθετη επιχειρηματική λογική.
Συχνές Ερωτήσεις
Το κύριο πρόβλημα είναι το Massive View Controller. Στο iOS, ο ελεγκτής UIViewController είναι υπεύθυνος για τα πάντα: επεξεργασία εισόδου, ενημέρωση View, εργασία με δίκτυο, πλοήγηση και κύκλο ζωής. Στο Android, το Activity/Fragment εκτελεί παρόμοιες λειτουργίες. Ως αποτέλεσμα, ο ελεγκτής μεγαλώνει σε χιλιάδες γραμμές κώδικα, γίνεται δύσκολος στη δοκιμή και συντήρηση, παραβιάζοντας την αρχή της μοναδικής ευθύνης.
Στο MVC, ο ελεγκτής ενημερώνει άμεσα το View και επεξεργάζεται την είσοδο χρήστη. Στο MVVM, τον ρόλο του ελεγκτή εκτελεί το ViewModel, το οποίο δεν έχει αναφορά στο View — τα δεδομένα μεταφέρονται μέσω μηχανισμών σύνδεσης. Το MVVM δοκιμάζεται καλύτερα, επειδή το ViewModel δεν εξαρτάται από το UIKit ή το Android Framework. Η Apple συνιστά MVVM με SwiftUI, η Google — MVVM με Jetpack Compose.
Ναι, το MVC παραμένει ένα λειτουργικό πρότυπο για απλές οθόνες και πρωτότυπα. Η Apple συνιστά MVC για εφαρμογές UIKit με απλές οθόνες. Για σύνθετα έργα με πολλές οθόνες, αιτήματα δικτύου και προσωρινή αποθήκευση, είναι καλύτερο να επιλέξετε MVVM, VIPER ή Clean Architecture. Σε αρχάριους προγραμματιστές συνιστάται να κατακτήσουν το MVC πριν από τη μελέτη πιο σύνθετων προτύπων.
Το Model δοκιμάζεται απομονωμένα — είναι συνηθισμένα αντικείμενα δεδομένων και επιχειρηματική λογική. Ο Controller είναι δύσκολο να δοκιμαστεί λόγω εξάρτησης από το UIKit ή το Android Framework. Συνιστάται η μεταφορά της επιχειρηματικής λογικής από τον ελεγκτή σε ξεχωριστές υπηρεσίες ή interactors, που δοκιμάζονται με μοναδιαίες δοκιμές. Το View συνήθως δεν δοκιμάζεται με μοναδιαίες δοκιμές — γι' αυτό χρησιμοποιούνται δοκιμές UI και δοκιμές στιγμιότυπων οθόνης.
Στο iOS — MVVM με SwiftUI και Combine, το πρότυπο της Apple από το 2019. Στο Android — MVVM με LiveData ή StateFlow, επίσημα συνιστώμενο από την Google. Για μεγάλα έργα με ομάδες από 5 προγραμματιστές — Clean Architecture με VIPER στο iOS ή Clean Architecture στο Android με διαίρεση σε ενότητες ανά λειτουργία. Για κληρονομικά έργα με MVC — σταδιακή αναδόμηση με μεταφορά λογικής σε ξεχωριστές υπηρεσίες.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης