Architettura MVC - Di quanti controller ho bisogno?


54

Ho programmato per un po 'di tempo, ma principalmente script e semplici applicazioni. Mi sono trasferito in un nuovo ruolo in cui si tratta dello sviluppo di app Web e dell'utilizzo di un'architettura MVC adeguata, quindi sto cercando disperatamente di imparare tutto molto rapidamente.

Spero che questa domanda non sia troppo simile a " Best Practices for MVC Architecture " ma, mentre sto esaminando alcuni tutorial diversi, ho notato che alcuni hanno controller multipli per cose diverse.

Di quanti controller è necessaria una singola app Web?

Mi rendo conto che sarebbe difficile rispondere senza un esempio, quindi ne fornirò uno:

Applicazione:

  1. L'utente accede.
  2. L'utente può eseguire una delle tre operazioni seguenti:
    a) Carica un file (memorizzato in un database mongodb con metadati).
    b) Cerca un file.
    c) Disconnettersi.

La mia domanda è generale, ma ho dato l'esempio per aiutare chiunque cerchi di rispondere.


8
Una domanda davvero ben fatta.
Daniel Hollinrake,

Risposte:


34

Per il tuo esempio, creerei due controller:

  • Controller sessioni per accesso e disconnessione (creare e distruggere la sessione per layout come REST)
  • File Controller per tutto sui file (indice = cerca e crea = carica)

In generale, un approccio RESTful in cui pensi a tutto come una risorsa che può essere visualizzata, creata, modificata e distrutta ti dà una buona idea su come strutturare le cose. Come puoi vedere dai miei esempi, non rimango troppo vicino ad ogni singolo verbo in REST.

Molto probabilmente avresti bisogno di più controller per ulteriori funzionalità. Ad esempio un Controller utenti in cui gli utenti possono creare nuovi account. Inoltre, è necessario disporre di un'interfaccia di amministrazione in cui è possibile modificare le risorse con privilegi più elevati. In tal caso è abbastanza comune avere quasi tutti i controller duplicati.

Una stima molto approssimativa per ottenere un'idea iniziale potrebbe essere un controller per ogni tabella del database a cui gli utenti possono accedere. Ma questa è davvero solo una misurazione molto grezza.


3
Prendendo il tuo esempio di amministratore: il controller di amministrazione estenderebbe l'utente generico o ridefinirebbe completamente tutti i metodi? Ad esempio, forse tutti gli utenti possono caricare e cercare, ma solo gli amministratori possono eliminare. La classe del controller di amministrazione erediterebbe solo tutti i metodi generali dell'utente?
Jeff,

4
Questo dipende molto dalla funzionalità effettiva, ma in generale scrivo semplicemente un secondo controller senza alcuna eredità. Seguendo il principio del "thin controller" non dovrebbe esserci comunque molto codice in un controller. E il controller di amministrazione può essere particolarmente semplice. Tutte le funzionalità importanti vanno nel modello. (ad esempio se l'eliminazione di un utente significa che anche tutti i suoi file devono essere eliminati, il modello gestisce questo, non c'è una sola riga per questo nel controller)
thorsten müller

6

Dipende davvero dall'app Web. Nel tuo esempio, probabilmente uno è sufficiente. Se dovessi implementare un'app di e-commerce completa con spedizione, tasse, gestione delle scorte, prezzi a livelli, ecc., Potresti volerne avere un altro paio.

Se il tuo controller soffre di uno o più odori di codice (specialmente Large Class o God Object ), allora sai che probabilmente hai superato il punto in cui solo uno farà.


5

Dipende molto dalle esigenze dell'applicazione e dall'architettura dei moduli aziendali.

Una regola generale , il numero di controller richiesti dipende da un numero di moduli e sottomoduli nell'app Web.

Come complemento, sarebbe utile organizzare i controllori in aree . Il concetto di aree è integrato nel framework ASP.NET MVC e semplifica l'organizzazione dei controller che servono un modulo.

Vi sono numerose discussioni correlate:


1
Grandi riferimenti! Sarò sicuro di controllarli!
Jeff,

Certo nessun problema.
EL Yusubov,

4

Mi piace il modo di fare di Apple.

Ogni vista è controllata da un solo controller di vista. ~ Visualizza la guida alla programmazione del controller per iOS

L'idea è che dovresti essere in grado di scambiare facilmente le viste. IMO, avendo solo 1 Controllerper Viewesso rende più facile farlo. Ma sono sicuro che potresti avere un controller con più viste e comunque progettarlo in modo da poter cambiare vista senza cambiare la logica del programma.


Questo è un buon punto, ma avresti bisogno di un controller per ogni vista più altri per occuparti di cose come gli utenti? Suppongo anche che se il mio progetto fosse più grande, avrebbe più senso avere più controller.
Jeff,

I modelli dovrebbero tenere traccia degli utenti. Pertanto, se necessario, più controller possono utilizzare lo stesso oggetto modello.
Korey Hinton,

2
Quindi un controller ha un oggetto Model e un oggetto View. Il controller richiede informazioni sull'oggetto Model (come le informazioni utente) e quindi imposta la vista di conseguenza. Il modello dovrebbe avere la maggior parte della logica del programma mentre il controller ha solo la logica per poter comunicare avanti e indietro tra la vista e il modello.
Korey Hinton,

2
Un controller per vista ha un design molto limitato, poiché il controller non sarebbe in grado di visualizzare diversi modelli di vista, per diversi stati del Modello.
EL Yusubov,

1
@ElYusubov Posso vedere dove potrebbe essere fonte di confusione. In iOS ogni vista ha un solo controller di visualizzazione e ogni controller di visualizzazione ha solo 1 vista attiva (e quella vista può avere viste secondarie) ma quel controller di vista può contenere anche riferimenti a qualsiasi numero di viste.
Korey Hinton,

2

Un esempio che mi piace è pensare a un termostato. Un termostato è un'ottima visuale per visualizzare il modello MVC.


Su un vecchio termostato analogico puoi immaginare cose come questa:

Visualizza : il lettore della temperatura, che visualizza la temperatura corrente.

Controller : quadrante in cui si modifica la temperatura

Modello : le parti interne invocate dal controller che causano il cambiamento della temperatura.


Dovresti sempre rispettare i progetti che consentono l'accoppiamento libero e limitano i modelli e i controller associati a una singola attività , e dovresti utilizzare tutti i moduli / controller di cui hai bisogno . A seconda delle dimensioni della tua applicazione, potresti avere molte meno visualizzazioni rispetto a modelli e controller. Questo è prevedibile con qualsiasi applicazione di grandi dimensioni. Una buona programmazione orientata agli oggetti è caratterizzata da accoppiamento libero, incapsulamento, ereditarietà e polimorfismo. Non tutte le lingue supportano il polimorfismo nella stessa misura (funzione, metodo, sovraccarico / esclusione dell'operatore).

Se si desidera comprendere meglio l'utilizzo corretto dell'architettura MVC, consultare il GoF "Design Patterns: Elements of Reusable ... Software" che utilizza C ++ e SmallTalk come codice di esempio. Questo libro non è l'alfa e l'omega, ma è certamente un inizio!

In bocca al lupo!


1

Presumo che il tuo esempio si evolverà in un sistema complesso.

Applicazione:

L'utente accede:

  • LoginController

La sua unica responsabilità è quella di gestire gli accessi, reindirizzare o informare l'utente del risultato.

Caricare un file

  • UploadController

Suppongo che tu voglia caricare qualsiasi tipo di file. Se in un secondo momento decidessi di caricare MP3 e PDF, allora avrei un UploadController di base, MP3UploadController e PDFUploadController.

Cerca un file.

  • SearchFileController

Ciò sarebbe sufficiente per un requisito di base. È possibile disporre di più controller di ricerca in un secondo momento, a seconda della complessità della logica di ricerca. L'ultima cosa che vuoi avere è un singolo SearchController con 20 metodi di azione che eseguono ricerche diverse.

Disconnettersi.

-LogoutController .

Si potrebbe considerare che ciò sia eccessivo, ma non credo che lo sia. Penso che sia pulito e ben separato.

Se dovessi guardare questa struttura del progetto, saprei immediatamente cosa fa e come è strutturata. Per fare un ulteriore passo avanti, vorrei mettere LoginControllere LogoutControllernella zona separata.

Ho sviluppato qualcosa di simile prima e ha funzionato davvero bene.


Grazie per l'input! Hai qualche codice funzionante? rimanere bloccati su alcune cose.
Jeff,

Quali problemi stai riscontrando?
CodeART

Sono in grado di caricare un soggetto e una data (in formato stringa) ma non riesco a caricare il file stesso (vedere stackoverflow.com/questions/18344614/… ).
Jeff,

Sono uno sviluppatore .NET. Mi dispiace, non posso aiutarti.
CodeART

1

La maggior parte del tuo codice sarebbe presente in un livello aziendale, giusto? In tal caso, tutto ciò che stai realmente facendo nel tuo controller è restituire i dati alla vista.

Non sono sicuro se sono un fan della separazione dei controller in sottotipi. Mentre dovresti mantenere la separazione delle preoccupazioni, penso che i sottotipi stiano andando un po 'troppo lontano. Inoltre, devi fare attenzione nei casi in cui oggetti pesanti sono inizializzati nel costruttore o in un controller. Ad esempio: nel tuo esempio vorresti che un oggetto pesante, usato solo per il file di ricerca / upload, fosse rilasciato quando l'utente si trova nella pagina di accesso.

È meglio avere un controller per unità logica, ad esempio AccountController (accesso, registrazione, disconnessione), FileController (ricerca, caricamento) e così via.


0

In generale si può dire che ogni MODELLO ha i propri CONTROLLER e VISUALIZZAZIONI dedicate. Dicendo generale intendo che questa è la migliore pratica.

Gli aspetti dell'applicazione (come la gestione degli utenti) devono essere tradotti in servizio dell'applicazione e devono essere richiamati dal controller stesso o per avvolgere il controller (utilizzando attributi che rendono la funzionalità del controller "visibile" in base al ruolo dell'utente richiesto, ad esempio).

Ricorda che tutti i controller dovrebbero sostanzialmente gestire le operazioni CRUD sul modello e utilizzare viste diverse per filtri diversi.

A mio avviso, uno dei principali vantaggi di MVC come modello è che offre il modo migliore per legare modelli e viste.

Sull'esempio che hai aggiunto: vorrei creare 2 controller: uno per tutte le operazioni di accesso dell'utente (registrazione, accesso, disconnessione ecc.) E il secondo per le operazioni sui file (caricamento e ricerca). si noti che il primo dovrebbe anche essere sottoposto a backup con alcuni aspetti relativi alla funzionalità di accesso e il secondo è controller ordinario


senza una spiegazione, questa risposta potrebbe diventare inutile nel caso in cui qualcun altro pubblichi un'opinione opposta. Ad esempio, se qualcuno pubblica un reclamo come "La gestione dei ruoli utente e dell'autorizzazione non dovrebbe essere in cima al controller" , in che modo questa risposta aiuterebbe il lettore a scegliere due opinioni opposte? Valuta di modificarlo in una forma migliore
moscerino il

1
@gnat Accetto il tuo commento, vedi la risposta modificata
Saturn Technologies
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.