MVC: l'essenza del pattern Model-View-Controller e la sua implementazione

Autore: IT Sectr Pubblicato: 2026-02-16 Tempo di lettura: 9 min

MVC (Model-View-Controller) è un pattern architetturale che divide un'applicazione in tre componenti: Model è responsabile dei dati e della logica di business, View è responsabile dell'interfaccia utente, Controller è responsabile dell'elaborazione degli input e del coordinamento tra Model e View. In iOS, MVC è implementato tramite UIViewController, in Android — tramite Activity e Fragment. MVC rimane il pattern fondamentale su cui sono costruiti MVVM, MVP e Clean Architecture. Scopri di più su MVC in Cocoa Core.

Punti chiave

  • MVC — tre componenti: Model (dati), View (interfaccia), Controller (logica)
  • UIViewController — implementazione di Controller su iOS, responsabile del ciclo di vita dello schermo
  • Activity/Fragment — implementazione di Controller in Android con funzioni simili
  • Massive View Controller — problema principale di MVC: il controller si gonfia fino a migliaia di righe
  • Comunicazione dei componenti — Controller aggiorna View e Model, Model notifica Controller dei cambiamenti

Cos'è MVC: l'essenza del pattern Model-View-Controller

MVC (Model-View-Controller) è un pattern architetturale proposto da Trygve Reenskaug nel 1979 per il linguaggio Smalltalk-80. Il pattern divide un'applicazione in tre strati: Model contiene dati e logica di business, View è responsabile della visualizzazione, Controller elabora l'input dell'utente e aggiorna Model e View. La separazione delle responsabilità consente di modificare ogni strato indipendentemente — ad esempio, sostituire View da UIKit a SwiftUI senza cambiare la logica di business in Model.

Interazione dei componenti in MVC segue un ciclo: l'utente interagisce con View → Controller riceve l'evento → Controller aggiorna Model → Model notifica Controller dei cambiamenti → Controller aggiorna View. Nell'implementazione classica, Model usa il pattern Observer: quando i dati cambiano, Model invia notifiche, Controller si sottoscrive e aggiorna View. Nell'implementazione Apple, Key-Value Observing (KVO) o NotificationCenter svolgono questo ruolo.

ComponenteResponsabilitàEsempio in iOSEsempio in Android
ModelDati, logica di business, reteStruct User, CoreDataData class, Repository
ViewVisualizzazione UIStoryboard, XIB, UIViewXML layout, Jetpack Compose
ControllerElaborazione input, coordinamentoUIViewControllerActivity, Fragment

MVC nello sviluppo mobile moderno è usato meno di 10 anni fa, ma rimane essenziale da capire. Apple raccomanda MVC per schermi semplici nelle applicazioni UIKit. Google non raccomanda MVC puro per Android — la documentazione ufficiale suggerisce MVVM con Jetpack. Tuttavia, la conoscenza di MVC è necessaria per lavorare con progetti legacy e per comprendere l'evoluzione dei pattern architetturali.

MVC in iOS: UIViewController e Storyboard

Apple MVC è un'implementazione personalizzata del pattern integrata in UIKit. UIViewController agisce come Controller: gestisce il ciclo di vita dello schermo (viewDidLoad, viewWillAppear, viewDidDisappear), gestisce tocchi e azioni dell'utente, aggiorna View tramite IBOutlets. View viene creata in Interface Builder (storyboard o XIB) o programmaticamente. Model — qualsiasi oggetto dati: servizi di rete, stack CoreData, strutture Swift.

swift
final class UserViewController: UIViewController {
    // View (tramite 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 aggiorna View
            self?.nameLabel.text = user.name
            self?.emailLabel.text = user.email
        }
    }
}

Il problema di Apple MVC — View e Controller sono strettamente accoppiati. UIViewController gestisce simultaneamente View e logica. Storyboard memorizza View in XML, ma il controller ha riferimenti diretti agli elementi UI tramite IBOutlets. Questo viola il principio di responsabilità unica: il controller è responsabile del ciclo di vita, delegati, datasource, target-action e animazioni. Di conseguenza, uno schermo standard di un'app iOS contiene 200–500 righe nel controller.

Ciclo di vita del ViewController — Apple fornisce 6 metodi del ciclo di vita: loadView (creazione manuale di View), viewDidLoad (dopo il caricamento di View in memoria), viewWillAppear (prima della comparsa sullo schermo), viewDidAppear (dopo l'animazione), viewWillDisappear (prima di lasciare lo schermo), viewDidDisappear (dopo aver lasciato). Ogni metodo è un posto per posizionare la logica in MVC. Usare questi metodi per la logica di business accelera la crescita del controller.

MVC in Android: Activity, Fragment e XML Layout

Android MVC — Activity e Fragment agiscono come Controller, i file XML layout come View, qualsiasi classe POJO con dati come Model. Activity gestisce il ciclo di vita dello schermo: onCreate, onStart, onResume, onPause, onStop, onDestroy. Fragment è un sottoschermo all'interno di Activity con il proprio ciclo di vita. View (XML) è separata da Controller e caricata tramite setContentView o LayoutInflater. Model — repository, database, chiamate di rete.

kotlin
class UserActivity : AppCompatActivity() {
    // View tramite XML layout
    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 e DataBinding — strumenti moderni che riducono l'accoppiamento tra Controller e View. ViewBinding genera una classe con riferimenti diretti alle Views da XML, eliminando findViewById. DataBinding aggiunge la possibilità di legare dati all'UI nel markup XML tramite @{user.name}. DataBinding è un passo verso MVVM, poiché consente di passare dati da Model a View senza codice in Activity. Google raccomanda DataBinding per tutti i nuovi progetti.

Ciclo di vita Android è più complesso di iOS: Activity può essere distrutta e ricreata durante la rotazione dello schermo, mancanza di memoria o cambio di configurazione. Nel puro MVC, il controller (Activity) contiene logica che viene persa alla distruzione. Ciò richiede il salvataggio dello stato tramite onSaveInstanceState o ViewModel da Jetpack, che va oltre il puro MVC e avvicina l'architettura a MVVM.

Massive View Controller e limitazioni di MVC

Massive View Controller è un termine che descrive il problema principale di MVC nello sviluppo mobile. Il controller in iOS e Android assume troppe responsabilità: elaborazione input, validazione dati, interazione di rete, navigazione, caching, animazioni, gestione del ciclo di vita. Di conseguenza, il controller si gonfia fino a 500–2000 righe di codice, diventando difficile da leggere, testare e mantenere.

Cause del Massive View Controller — l'architettura di UIKit e Android Framework incoraggia a posizionare la logica nel controller. Chiamate di rete, elaborazione JSON, navigazione — tutto questo finisce naturalmente in Activity o UIViewController perché hanno accesso al ciclo di vita e all'UI. Lo sviluppatore deve consapevolmente estrarre la logica in classi separate (Service, Manager, Interactor), il che richiede disciplina e comprensione dei principi architetturali.

Problema di MVCDescrizioneSoluzione
Forte accoppiamentoController conosce View e ModelMVVM — ViewModel non conosce View
Complessità di testController dipende da UIKit/AndroidEstrarre logica in servizi
Ciclo di vitaLo stato viene perso alla rotazioneViewModel da Jetpack/SwiftUI
Mancanza di navigazioneController gestisce le transizioniPattern Coordinator, Router

Test di MVC — Model viene testato isolatamente con test unitari. Controller è difficile da testare a causa della dipendenza da UIKit/UIFoundation. XCTest non consente di creare UIViewController senza una finestra di visualizzazione. Per Android, ActivityTestRule e Robolectric risolvono parzialmente il problema, ma i test sono lenti. View di solito non viene testata con test unitari — per l'UI vengono utilizzati test screenshot e test UI (XCUITest, Espresso).

Quando MVC è giustificato — schermi semplici con uno o due elementi (schermo di login, profilo, impostazioni). Prototipi e MVP per la validazione di ipotesi — MVC è più veloce da scrivere senza strati aggiuntivi. Progetti con base di codice piccola fino a 10–15 schermi. Nei progetti complessi, MVC porta all'accumulo di debito tecnico e richiede refactoring ogni 6–12 mesi.

Confronto di MVC con MVVM, MVP e Clean Architecture

MVC vs MVVM — la differenza principale: in MVVM, il controller è sostituito da ViewModel che non ha riferimento a View. I dati vengono passati tramite Observable (SwiftUI), LiveData/StateFlow (Android) o Combine/RxSwift. ViewModel è testabile con test unitari senza dipendenze UI. Apple raccomanda MVVM con SwiftUI dal 2019, Google — MVVM con LiveData/Flow come architettura ufficiale Android. MVVM richiede più codice per il binding ma migliora significativamente la testabilità.

MVC vs MVP — in MVP (Model-View-Presenter), Presenter è uno strato testabile che riceve View tramite un'interfaccia. A differenza di MVC dove Controller gestisce direttamente View tramite UIKit, Presenter non dipende dal framework — funziona tramite l'astrazione ViewInterface. MVP era popolare nello sviluppo Android prima di Jetpack ed è utilizzato in progetti legacy. Presenter sopravvive ad Activity e preserva lo stato alla rotazione dello schermo.

MVC vs Clean Architecture — Clean Architecture aggiunge strati: Use Cases (Interactors), Entities, Gateways e Repository. MVC rimane nello strato Presentation, ma la logica di business viene spostata nello strato Domain con Use Cases. Clean Architecture risolve radicalmente il problema del Massive View Controller — Controller contiene solo chiamate Use Cases e aggiornamenti di View. Lo svantaggio è un aumento significativo del numero di classi e file, giustificato per progetti con 50+ schermi.

swift
// MVC in iOS: Controller contiene tutto
class OrderViewController: UIViewController {
    func placeOrder() {
        // Validazione + rete + aggiornamento UI
        guard Validation.isValid(total) else { return }
        NetworkService.shared.submit(order) { [weak self] result in
            self?.handleResult(result)
        }
    }
}

// MVVM: logica in ViewModel
class OrderViewModel: ObservableObject {
    @Published var state: OrderState = .idle
    func placeOrder() { /* logica di business */ }
}

Scelta dell'architettura dipende dalle dimensioni del team, dall'ambito del progetto e dalla testabilità richiesta. Per un team di 1–2 sviluppatori e un progetto fino a 20 schermi, MVVM funziona bene. Per un team grande di 5+ sviluppatori e un progetto con 50+ schermi — Clean Architecture con struttura modulare. MVC rimane rilevante per comprendere l'evoluzione delle architetture, mantenere progetti legacy e per schermi UIKit semplici senza logica di business complessa.

Domande frequenti

Qual è il problema principale di MVC nello sviluppo mobile?

Il problema principale è il Massive View Controller. In iOS, UIViewController gestisce tutto: elaborazione input, aggiornamento View, rete, navigazione e ciclo di vita. In Android, Activity/Fragment svolge funzioni simili. Di conseguenza, il controller si gonfia fino a migliaia di righe di codice, diventando difficile da testare e mantenere, violando il principio di responsabilità unica.

In cosa MVC differisce da MVVM?

In MVC, il controller aggiorna direttamente View ed elabora l'input dell'utente. In MVVM, il ruolo del controller è svolto da ViewModel, che non ha riferimento a View — i dati vengono passati tramite meccanismi di binding. MVVM è più facile da testare perché ViewModel non dipende da UIKit o Android Framework. Apple raccomanda MVVM con SwiftUI, Google raccomanda MVVM con Jetpack Compose.

Si può usare MVC nei progetti moderni?

Sì, MVC rimane un pattern funzionante per schermi semplici e prototipi. Apple raccomanda MVC per applicazioni UIKit con schermi semplici. Per progetti complessi con molti schermi, richieste di rete e caching, è meglio scegliere MVVM, VIPER o Clean Architecture. I principianti sono invitati a padroneggiare MVC prima di apprendere pattern più complessi.

Come testare un'applicazione MVC?

Model viene testato isolatamente — sono normali oggetti dati e logica di business. Controller è difficile da testare a causa della dipendenza da UIKit o Android Framework. Si consiglia di estrarre la logica di business dal controller in servizi o interactor separati, che vengono testati con test unitari. View di solito non viene testata con test unitari — vengono utilizzati test UI e test screenshot.

Quale pattern scegliere dopo MVC?

Su iOS — MVVM con SwiftUI e Combine, standard Apple dal 2019. Su Android — MVVM con LiveData o StateFlow, ufficialmente raccomandato da Google. Per grandi progetti con team di 5+ sviluppatori — Clean Architecture con VIPER su iOS o Clean Architecture su Android con separazione dei moduli per funzionalità. Per progetti legacy con MVC — refactoring graduale con estrazione della logica in servizi separati.

Riepilogo

  • MVC — pattern architetturale con separazione in Model, View e Controller
  • iOS MVC — UIViewController + storyboard + servizi dati
  • Android MVC — Activity/Fragment + XML layout + repository
  • Massive View Controller — problema principale a causa della mescolanza di responsabilità
  • Test — Model è facile da testare, Controller richiede estrazione della logica
  • Evoluzione — MVC → MVVM → Clean Architecture per progetti in crescita
  • Compatibilità — i pattern possono essere combinati nello stesso progetto

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche