Il pattern Model-View-Controller (MVC) è un classico pattern architetturale, nato molto prima di Swift e utilizzato per separare dati, interfaccia utente e logica di controllo. Nella storia dello sviluppo iOS, MVC è stato proclamato da Apple come il principale pattern architetturale per la costruzione di applicazioni in Objective-C e Swift.
Il principale problema del MVC standard è che, col tempo, i controller diventano "Massive View Controllers", combinando logica di business, interazione con il modello, gestione dell'input dell'utente e persino logica di visualizzazione. Questo porta a una diminuzione della leggibilità, della riutilizzabilità e della testabilità del codice.
In Swift, MVC è implementato utilizzando le classi UIViewController per il controller, modelli come strutture o classi, e UIView per costruire l'interfaccia. Il controller collega il modello e la vista, avviando l'aggiornamento dell'interfaccia quando i dati cambiano.
Esempio di codice:
struct User { let name: String let age: Int } class UserView: UIView { let nameLabel = UILabel() func display(user: User) { nameLabel.text = "\(user.name), \(user.age) anni" } } class UserController: UIViewController { var user: User? var userView: UserView! override func loadView() { userView = UserView() view = userView } override func viewDidLoad() { super.viewDidLoad() if let user = user { userView.display(user: user) } } }
Caratteristiche principali:
È possibile avere dipendenze dirette tra la Vista e il Modello in MVC?
No, la Vista non dovrebbe interagire direttamente con il Modello. Tutte le comunicazioni avvengono esclusivamente tramite il Controller; altrimenti, il modello "scopre" la vista, violando il principio di separazione delle responsabilità e ostacolando la scalabilità.
Il Controller può contenere dati e logica di livello business?
Spesso si pensa erroneamente che il controller possa contenere logica di business. In realtà, la logica di business dovrebbe essere separata nel Modello o in servizi distinti, mentre il controller deve semplicemente gestire il ciclo di vita della Vista e la sincronizzazione dei dati.
Come affrontare i controller massivi (Massive View Controller)?
Per combattere i controller massivi, spostate la gestione dei dati dal controller al Modello o ai servizi, utilizzate delegati, patterns di delega e composizione. Create classi separate per configurare la Vista o incorporate la logica di visualizzazione direttamente nella Vista.
Nel progetto, il controller conteneva sia i dati dell'utente che la loro elaborazione e il codice di visualizzazione. Risultò impossibile riutilizzare la logica in un altro controller e fu molto difficile testare la logica di business.
Pro:
Contro:
Il Modello si occupa solo dei dati e della logica di business, la Vista disegna l'interfaccia, il Controller le collega. È emersa la possibilità di riutilizzare componenti, testare e scalare l'applicazione più rapidamente.
Pro:
Contro: