In un'architettura MVC, quanto sono strettamente connessi il modello e la vista del controller?

15

Ho un'app che usa MVC, ma sto facendo fatica a capire come deve essere progettato il controller. Ad esempio, la vista sta visualizzando solo alcuni sottoinsiemi dei dati del modello contemporaneamente. Tuttavia, non sono sicuro di come esattamente dovrebbe essere organizzato. È normale che la vista o il modello richiamino direttamente funzioni sul controller, ad esempio? Attraverso una sorta di interfaccia? Oppure sono totalmente incapsulati e non conoscono mai il Controller o l'un l'altro?

Proprio come una modifica; questa è un'app personalizzata non scritta in nessun framework web, quindi non sto cercando dettagli specifici di framework qui e ho la libertà di fare la mia scelta.

    
posta DeadMG 12.05.2012 - 22:04
fonte

7 risposte

14

Il controller controlla il flusso di attività. L'utente esegue questa azione, il controllore passa i dati della vista al dominio che fa tutto ciò che deve fare, quindi, in base alla / e risposta / e, il controllore comunica al framework quale vista mostrare successivamente (e gli dà abbastanza dati da fare così).

Il controller deve quindi essere accoppiato al modello di dominio, in una certa misura. vale a dire. È possibile inserire un livello di servizio intermedio ma, per definizione rigorosa, diventa parte del dominio.

È anche accoppiato ai dati della vista ma non alla vista stessa. vale a dire. dice semplicemente "mostra la visualizzazione del cliente utilizzando questo dettaglio cliente". Il framework decide quindi dove dovrebbe trovare quella vista.

Ora questo dovrebbe consentire di disaccoppiare il modello di dominio dalla vista, usando un modello di vista degli stessi dati. Alcuni sviluppatori lo fanno, altri no, e penso che sia in gran parte una questione di preferenze personali.

In Rails, sei molto incoraggiato a spingere gli oggetti del dominio (ActiveRecord) alla vista e confidare che la vista non sfrutti tale accesso (ad esempio non devi chiamare customer.save dalla vista, anche se sarebbe disponibile)

Nel mondo .NET, tendiamo a ridurre il rischio non consentendo cose che non dovrebbero accadere e, probabilmente per quel motivo, mi sembra che il modello di vista distaccato sia più popolare.

    
risposta data 13.05.2012 - 00:09
fonte
7

Nota: Robert C. Martin (alias Zio Bob) lo spiega in modo molto migliore e divertente nella sua nota chiave, Architecture the Lost Years . Un po 'lungo ma insegna molti buoni concetti.

tl; dr: non pensare e pianificare la tua app in termini di MVC. Il framework MVC è solo un dettaglio di implementazione.

La cosa più confusa su MVC è che gli sviluppatori cercano di utilizzare tutti i componenti incollati insieme.

Prova a pensare nei termini di un programma, non nei termini del framework.

Il tuo programma ha uno scopo. Richiede alcuni dati, fa le cose con i dati e restituisce alcuni dati.

In questo modo, controller è il meccanismo di consegna del tuo programma.

  1. Un utente invia una richiesta al tuo programma (diciamo, aggiungi un prodotto al carrello).
  2. Il controllore accetta quella richiesta (informazioni sul prodotto e informazioni utente), chiama la parte necessaria del tuo programma che gestirà questa richiesta $user->addToCart($product)
  3. Il tuo programma (funzione addToCart dell'oggetto user in questo caso) esegue il lavoro che intende eseguire e restituisce una risposta (diciamo success )
  4. Il controllore prepara la risposta utilizzando il view pertinente: es. nell'oggetto controller $this->render($cartView('success')

In questo modo, i controller vengono disaccoppiati dal programma e utilizzati come meccanismo di consegna. Non sanno come funziona il tuo programma, sanno solo quale parte del programma deve essere chiamata per le richieste.

Se vuoi utilizzare un altro framework, la tua app non avrà bisogno di modifiche, dovrai solo scrivere dei controller rilevanti per chiamare il tuo programma per le richieste.

O se vuoi creare una versione desktop, la tua app rimarrà la stessa, dovrai solo preparare un meccanismo di consegna.

E Model . Pensalo come un meccanismo di persistenza.

Nel modo OO, ci sono oggetti nel tuo programma che contiene i dati.

class User {
    //...
    private $id;
    private $shoppingCart;
    //...
}

class Product {
    //...
    private $id;
    //...
}

Quando aggiungi un prodotto al carrello, puoi aggiungere product::id a user::shoppingCart .

E quando si desidera mantenere i dati, è possibile utilizzare la parte model del framework, che generalmente consiste nell'utilizzo di un ORM, per associare le classi alle tabelle del database.

Se vuoi cambiare l'ORM che usi, il tuo programma rimarrà invariato, cambieranno solo le informazioni di mappatura. Oppure, se vuoi evitare i database tutti insieme, puoi semplicemente scrivere i dati in file di testo normale e la tua app rimarrà la stessa.

Quindi, scrivi prima il tuo programma. Se si programma con il modo "OO", utilizzare semplici vecchi oggetti della lingua. Non pensare in termini di MVC all'inizio.

    
risposta data 13.05.2012 - 15:17
fonte
2

Martin Fowler fa un buon lavoro nel descrivere il paradigma MVC. Ecco un link al suo articolo su di esso link

Nota la sua citazione sulla Presentazione Separata "L'idea alla base della Presentazione Separata è quella di creare una chiara divisione tra gli oggetti del dominio che modellano la nostra percezione del mondo reale e gli oggetti di presentazione che sono gli elementi della GUI che vediamo sullo schermo."

    
risposta data 12.05.2012 - 22:20
fonte
1

Ecco un semplice esempio di come MVC può essere utilizzato in una tipica applicazione Java Swing ...

Supponiamo che tu abbia un pannello contenente un pulsante e un campo di testo. Quando viene premuto il pulsante, viene generato un evento, che porta a qualche cambiamento di stato nell'applicazione. Una volta registrato il cambiamento di stato, TextField viene disabilitato.

Questo, quindi, sarebbe l'approccio tipico adottato da una semplice applicazione MVC ...

Il controller si registra come l'ascoltatore degli eventi della vista. Quando si fa clic sul pulsante, la vista stessa non gestisce l'evento; il controller lo fa. Il controller è specifico per Swing in quanto deve gestire gli eventi relativi a Swing.

Il controllore riceve questa notifica e deve decidere chi deve gestirlo (la vista o il modello). Poiché questo evento cambia lo stato dell'applicazione, decide di inoltrare le informazioni al modello responsabile della logica dei dati e del programma. Alcuni fanno l'errore di posizionare la logica del programma nel controller ma in OOP, i modelli rappresentano sia il comportamento AND dei dati. Leggi Martin Fowler sulla sua interpretazione di questo.

Il messaggio è ricevuto dal Modello nel giusto contesto. Cioè, è completamente privo di riferimenti a Swing o altri riferimenti specifici della GUI. Questo messaggio parla al modello e SOLO al modello. Se ti trovi a importare istruzioni javax.swing nel modello, non stai codificando il modello correttamente.

Il modello imposta quindi il suo stato su "disattivato" e procede a notificare a qualsiasi parte interessata questa modifica del modello. La View, essendo interessata a questo evento, si è già registrata come Observer di qualsiasi cambio di modello. Una volta che l'evento di modifica dello stato del modello viene rilevato dalla vista, procede a disabilitare il suo campo di testo. È anche legale per la View ottenere informazioni di sola lettura direttamente dal suo Modello senza dover passare attraverso il Controller (solitamente attraverso un'interfaccia specifica esposta dal Modello per tale attività)

Promuovendo un accoppiamento così lento tra la presentazione e la logica aziendale e i livelli dati, troverai che il tuo codice è molto più gestibile. Man mano che i sistemi crescono, anche il tuo approccio a MVC. Ad esempio, Hierarchical MVC è un'estensione usata spesso per collegare le triadi MVC insieme per formare grandi sistemi aziendali senza accoppiare sottosistemi insieme

    
risposta data 05.08.2013 - 07:10
fonte
0

L'accoppiamento (l'ordinamento che si desidera evitare) implica una dipendenza reciproca tra due classi. Cioè, un Foo dipende da una Barra e una Barra dipende da un Foo in modo che non si possa realmente modificarne uno senza modificare l'altro. Questa è una brutta cosa.

Non puoi davvero evitare di avere alcune dipendenze, comunque. Le classi devono conoscersi un po 'l'un l'altro, altrimenti non avrebbero mai comunicato.

Nel pattern MVC, il controller controlla la comunicazione tra il modello di dominio e la vista di presentazione. In quanto tale, il Controller deve conoscere abbastanza il Modello per chiedergli di fare ciò che deve fare. Il Controller deve anche conoscere abbastanza la Vista per poterlo presentare al cliente o agli utenti. Quindi, il controllore Modello ha dipendenze da entrambi. Tuttavia, la vista può esistere perfettamente senza il controller: non c'è dipendenza da lì. Allo stesso modo, il modello non ha alcuna dipendenza dal controller: semplicemente è quello che è. Infine, il modello e la vista sono completamente separati l'uno dall'altro.

Essenzialmente, il Controller è il livello di riferimento indiretto che disaccoppia la Vista dal Modello, in modo che non debbano conoscersi l'un l'altro.

    
risposta data 13.05.2012 - 00:25
fonte
-5

Nella mia esperienza, generalmente il modello dipende solo dalla vista a , non da uno specifico, spesso come osservatore ... se ha un tale accoppiamento.

La vista generalmente si associa a qualsiasi cosa stia guardando, il che ha senso. È difficile trovare una vista che possa essere disaccoppiata da ciò che sta guardando ... ma a volte puoi avere un accoppiamento parziale o qualcosa del genere.

Il controller tende spesso ad accoppiarsi ad entrambi. Ciò ha anche senso poiché è compito trasformare gli eventi della vista in modifiche del modello.

Naturalmente, questa è solo una tendenza che ho osservato e in realtà non dice nulla su alcun esempio specifico.

Per capire cosa sia MVC e quale sia la relazione di accoppiamento, dovresti esaminare come è nato MVC. L'ambiente in cui è stato creato MVC era uno in cui i "widget" come elementi di forma con cui è possibile creare finestre di dialogo non esistevano. Una "vista" era una scatola e disegnava cose. Una vista testuale sarebbe una scatola che disegnerebbe il testo. Una visualizzazione elenco era una casella che disegnava un elenco. Il "controller" ha ricevuto tutti gli eventi del mouse e della tastiera dal sistema dell'interfaccia utente che si è svolto in quella vista; non ci sono stati eventi "textChanged" o "selectionChanged". Il controller prenderebbe tutti questi eventi di basso livello e genererebbe interazione con il modello. Il modello, dopo essere stato modificato, avrebbe notificato le sue opinioni; da allora siamo venuti a vedere questa relazione come "osservatore" ed è usata in altri modi come modello.

QUESTA è l'essenza del pattern MVC. Poiché questo tipo di programmazione dell'interfaccia utente di basso livello non viene generalmente eseguita, MVC si è evoluto in molte direzioni diverse. Alcune cose che oggi hanno quel nome non assomigliano affatto all'MVC e dovrebbero essere chiamate qualcos'altro. Può ancora essere usato anche se nel senso di un dialogo nel suo complesso che interagisce con un oggetto più grande. Ci sono molte alternative migliori però.

Fondamentalmente, tutto ciò che l'MVC doveva risolvere avviene all'interno dei widget ora ed è qualcosa che non dobbiamo più usare.

Per quelli che pensano di sapere meglio:

link

link

Sono sicuro che ce ne sono altri, ma quelli sono solo in cima alla lista di google. Come potete vedere, il modello dipende molto da un'interfaccia vista in MOLTE implementazioni. Generalmente un modello è osservabile e la vista è un osservatore.

Ma perché lasciare che i fatti si intromettano ...

Un articolo già pubblicato in un'altra risposta supporta anche le mie dichiarazioni:

link

Se le persone vogliono continuare a dire che TUTTI nel settore del design sono sbagliati, allora va bene.

    
risposta data 13.05.2012 - 00:45
fonte
-7
  • Il controllore invia il modello a una vista e elabora il modello presentato dalle viste, tuttavia non è strettamente accoppiato a una vista oa un modello.

Se il controller fosse strettamente collegato a una vista, allora saremo in un mondo di moduli Web. Avresti un codice dietro il quale verrebbe legato a un file modello (applicabile ai moduli Web ASP.NET)

Per questo motivo, il controller non è accoppiato a un modello o una vista. È solo un meccanismo per elaborare richieste e inviare risposte.

  • La vista è strettamente accoppiata a un modello. Apporta modifiche al tuo modello (ad esempio modifica la sua proprietà) e dovrai apportare modifiche alla tua vista.

  • Il modello non è strettamente associato a una vista. Apporta modifiche a una vista e non avrà alcun effetto su un modello.

  • Il modello non sa nulla del controller o delle viste in cui può essere utilizzato. Pertanto, il modello non è strettamente accoppiato a una vista oa un controller.

Un altro modo per pensarci:

  • Apporta modifiche a un controller: la vista e il modello non saranno modificati

  • Apporta modifiche a un modello: la vista si interromperà in quanto si basa su un modello

  • Apporta modifiche a una vista: il modello e il controller non saranno interessati

Questo accoppiamento lento nei progetti MVC è ciò che li rende facili da testare.

    
risposta data 13.05.2012 - 15:38
fonte

Leggi altre domande sui tag