Su MVC diverse viste possono avere lo stesso controller o una vista deve avere un controller univoco?


15

Sto avendo alcune domande durante la progettazione di un'architettura per un progetto attorno a MVC. (È un progetto SDK C ++ / Marmalade, non sto usando alcun framework MVC particolare, ne sto realizzando uno.)

Su diversi articoli (come sull'articolo originale di Steve Burbek ) continuo a leggere il concetto di "triade MVC" che mi tormenta da quando ho preso questo concetto piuttosto letteralmente. Quando l'ho letto la prima volta sembrava che un'applicazione fosse costruita attorno alle unità "triade MVC" - una per ogni pezzo dell'interfaccia utente che supponevo -, ma lo trovo piuttosto poco flessibile e penso che non sia così che MVC avrebbe dovuto essere usato. Quindi, approfondendo ulteriormente la questione, ho trovato diversi esempi di accoppiamento stretto tra controller e vista, vale a dire la relazione 1 a 1: TextEditView ha TextEditController.

Ma quando torno al mio progetto trovo che potrebbe essere utile avere un controller (per "unità logica", come AddElementController) e diverse viste per quel controller specifico.

Sto chiaramente pensando a qualcosa come un AddElementController che dovrebbe avere una sorta di interfaccia utente a schede. Dovrei avere un AddElementController che ha un AddElementTabView e diversi AddImageView, AddSoundView, ecc. Per le schede? O dovrei avere un 'sub-controller' diverso per ogni vista della scheda?

In breve, e per quanto riguarda il modello MVC (non la comprensione / implementazione particolare del framework X di questo modello), è corretto avere più viste per un controller o ogni vista dovrebbe avere il suo controller particolare?

Inoltre, è corretto conservare alcune informazioni sullo stato sul controller o dovrebbe essere apolide (il che significa che lo stato dovrebbe essere posizionato su un modello di stato non di dominio)?

Grazie a tutti in anticipo.

Risposte:


14

Il problema è che il modello MVC è stato progettato in un sistema che non esiste più. È stato inventato in Smalltalk in un momento in cui le librerie UI non esistevano. Per creare una finestra di dialogo hai disegnato tutte le caselle, evidenziato i quadrati appropriati, assicurandoti che il testo che stavi disegnando sia finito nel punto giusto ... ecc ...

Immagina come sarebbe scrivere un'app di dialogo usando nient'altro che una grande tela. Questo è il mondo da cui proviene MVC.

Una "vista" in questo sistema era una casella di testo ed era una classe che era responsabile per disegnare la casella, il testo, disegnare aree selezionate, rispondere alle modifiche nel testo, ecc ...

Un "controller" era un'altra classe che prendeva eventi del mouse che si verificavano all'interno di questo riquadro come spostamento del mouse, tasto giù, tasto su, clic, ecc ... e avrebbe deciso cosa sarebbe successo. Dovremmo cambiare il testo? Dovremmo cambiare la selezione? Roba del genere.

Un "modello" era ancora un'altra classe che rappresentava i dati di base e lo stato del componente. Un modello di casella di testo avrebbe ovviamente il testo, il carattere, la selezione, ecc ...

Come puoi vedere, in una situazione come questa i tre componenti sono molto coinvolti nella rappresentazione di una singola idea. In questo contesto ha senso parlare di "triade".

Oggi, se stai lavorando alla creazione di una libreria UI e all'uso di comandi di disegno non elaborati, potresti fare qualcosa di simile. Ma l'applicazione del modello "MVC" si è estesa oltre il suo scopo iniziale. Oggi hai una "vista" che in realtà potrebbe essere una finestra di dialogo completa e un controller che risponde a eventi come "textChanged" o "buttonClicked". Il modello nell'MVC di oggi è normalmente qualcosa di piuttosto disconnesso dal sistema (ma generalmente collegato alla vista fornendo un'interfaccia osservatore di qualche tipo) e potrebbero esserci molte viste associate a un modello.

In un sistema che ho recentemente progettato, ad esempio, avevamo circa 10+ viste tutte osservando un unico "titolare" del documento e il suo documento attivo. Un'interfaccia di disegno principale interagiva con il layout del documento, varie viste di proprietà che osservavano l'elemento selezionato e fornivano un'interfaccia di registrazione e una rappresentazione in scala minore della vista principale che mostrava l'intero documento anziché solo la finestra visibile. Alcune di queste viste avevano controller di varia complessità che trasformavano gli eventi della GUI in modifiche al documento, che a loro volta avrebbero notificato le sue varie viste.

Puoi ancora definire una relazione del genere una "triade"? Forse, ma penso che implichi troppo della precedente, vecchia applicazione di MVC.

Potresti condividere controller con viste diverse? Dipende da quanto simili sono le viste. Ho scoperto che in generale questo tipo di oggetto ha un comportamento specifico per la vista che sta controllando E il modello che sta manipolando per essere molto riutilizzabile ... ma ci sono sempre delle eccezioni.


5

Dipende. Esistono diverse varianti di MVC, alcune in cui ha senso solo una relazione 1: 1 (come "l'umile finestra di dialogo"), altre in cui non è così. Consiglio di leggere la serie di articoli " Build Your Own CAB ", che spiega le varianti MVC più importanti.


3

Le visualizzazioni non hanno controller in MVC. Il controller è il capo, quindi un controller decide quale vista rendere e alle viste non importa / non può importare quale controller ha richiesto la vista.

Puoi / avrai assolutamente più visualizzazioni da un controller. Pensa solo alla creazione di un modello per ogni vista se vuoi restare fedele al modello MVC.


3

Il punto del controller è controllare le interazioni dell'utente con il tuo modello di dominio, ovvero è un livello di riferimento indiretto tra ciò che l'utente vede (la vista) e lo stato delle tue applicazioni (il modello).

Quando l'utente effettua una richiesta, viene indirizzata a un controller. Il controller decide come inoltrare tale richiesta all'applicazione, generalmente tramite una sorta di classe di servizio. Quindi interpreta la risposta di quella classe di servizio e decide quale vista inviare nuovamente all'utente.

Un controller può sempre restituire la stessa vista (1: 1) se esiste un solo tipo di richiesta che l'utente può fare al controller e richiede sempre lo stesso tipo di risposta. Ad esempio, HelloWorldControllerverrà sempre restituito il messaggio HelloWorldView"Ciao, mondo!"

D'altra parte, un controller deve spesso decidere su viste diverse, a seconda di ciò che dice il modello. Il TeamRosterControllerpotrebbe restituire un RugbyTeamRosterViewo FootbalTeamRosterView, a seconda del tipo di squadra richiesto.

È generalmente preferibile che i controller siano apolidi, sebbene un certo accesso allo stato della sessione utente possa essere necessario o desiderabile. Se possibile, è necessario gestire l'accesso a tale stato separatamente.

Consiglio vivamente di guardare un vero framework MVC per vedere cosa fa e come funziona. Non devi usarlo, ma sicuramente acquisiresti una migliore comprensione prima di costruirne uno tuo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.