In un'architettura MVC, quanto sono strettamente collegati il ​​modello e la vista al controller?


16

Ho un'app che utilizza MVC, ma sto lottando un po 'su come il controller dovrebbe essere progettato. Ad esempio, la vista visualizza solo alcuni sottogruppi di dati del modello contemporaneamente. Tuttavia, non sono sicuro di come dovrebbe essere organizzato. È normale, ad esempio, per View o Model chiamare direttamente le funzioni sul controller? Attraverso una sorta di interfaccia? O sono totalmente incapsulati e non conoscono mai il Controller o l'altro?

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


1
Non risponderò perché la mia esperienza è limitata nelle architetture MVC, ma da tutto ciò di cui ho sentito e parlato con altri, l'M & V sono strettamente accoppiati tra loro ma non il C. L'M generalmente chiama funzioni sul C e il V spesso collega solo alcuni sottogruppi di M.
Steven Evers

8
@SnOrfus: è esattamente l'opposto di quello che pensavo: l'M & V sono accoppiati alla C ma non l'uno all'altro.
DeadMG

1
Come possono tante risposte essere così sbagliate? Qui lettura di MS versione msdn.microsoft.com/en-us/library/ff649643.aspx
Reactgular

Risposte:


15

Il controller controlla il flusso di attività. L'utente esegue questa azione, il controller passa i dati della vista al dominio che fa tutto ciò che deve fare quindi, in base alla risposta (e), il controller dice al framework quale vista mostrare successivamente (e gli fornisce dati sufficienti per 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 nel mezzo ma, per definizione rigorosa, che diventa parte del dominio.

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

Ora questo dovrebbe consentire di separare 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 di dominio (ActiveRecord) nella vista e ti fidi che la vista non sfrutti tale accesso (es. Non dovresti chiamare customer.save dalla vista, anche se sarebbe disponibile).

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


1
Visualizza modello è una pratica molto comune quando si tratta di test unitari. Normalmente si mappa automaticamente il modello di dominio o un oggetto DTO su un modello di vista. Dovresti quindi utilizzare il tuo modello di vista in una vista. Visualizza modello è facilmente testabile e non è legato a un livello sottostante.
CodeART,

7

Nota: Robert C. Martin (aka Zio Bob) lo spiega in modo molto migliore e divertente nel suo keynote, 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 usare tutti i componenti incollati insieme.

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

Il tuo programma ha uno scopo. Prende alcuni dati, fa 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 controller accetta quella richiesta (informazioni sul prodotto e informazioni sull'utente), chiama la parte necessaria del programma che gestirà questa richiesta $user->addToCart($product)
  3. Il tuo programma ( addToCartfunzione userdell'oggetto in questo caso) fa il lavoro che deve fare e restituisce una risposta (diciamo success)
  4. Il responsabile del trattamento prepara la risposta utilizzando i pertinenti view: ad 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 desideri utilizzare un altro framework, la tua app non avrà bisogno di modifiche, dovrai solo scrivere controller pertinenti per chiamare il tuo programma per le richieste.

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

E il Model . Pensalo come un meccanismo di persistenza.

In modo OO, ci sono oggetti nel tuo programma che contengono i dati.

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

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

Quando aggiungi un prodotto al carrello, puoi aggiungere il product::idaluser::shoppingCart .

E quando vuoi conservare i dati, puoi usare model parte del framework, che generalmente consiste in un ORM, per mappare le classi alle tabelle del database.

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


Quindi, scrivi prima il tuo programma. Se stai programmando con il modo 'OO', usa semplici vecchi oggetti del linguaggio. Non pensare in termini di MVC all'inizio.


Bel video. Grazie. Non sarei d'accordo con la tua interpretazione di esso però. MVC non è un dettaglio nel significato che c'è lo zio Bob. Noterai che MVC è un modello architettonico molto simile al suo modello "Interactor / Entity / Boundary" che sta stabilendo. D'altra parte, qualsiasi particolare sistema MVC, come Spring o altro, è davvero qualcosa che sta raccomandando di rinviare. Come spiega, però, questi framework chiamati "MVC" sono una specie di bastardizzazione del termine.
Edward Strange,

Sì, l'ho scritto nel modo in cui le persone pensano cosa MVCsia. Ecco perché ho scritto MVC Framework.
Hakan Deryal,

2

Martin Fowler fa un buon lavoro nel descrivere il paradigma MVC. Ecco un link al suo articolo su di esso http://martinfowler.com/eaaDev/uiArchs.html

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


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 si preme il pulsante, viene generato un evento, con conseguente cambiamento di stato nell'applicazione. Una volta registrato il cambio di stato, TextField viene disabilitato.

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

Il controller si registra come 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 di Swing in quanto deve gestire gli eventi relativi a Swing.

Il controller riceve questa notifica e deve decidere chi deve gestirla (la vista o il modello). Poiché questo evento cambierà lo stato dell'applicazione, decide di inoltrare le informazioni al Modello responsabile della logica dei dati e del programma. Alcuni commettono l'errore di inserire la logica del programma nel controller ma in OOP, i modelli rappresentano sia i dati che il comportamento. Leggi Martin Fowler sul suo approccio.

Il messaggio viene ricevuto dal modello nel contesto appropriato. Cioè, è completamente privo di qualsiasi riferimento a Swing o qualsiasi altro riferimento specifico della GUI. Questo messaggio parla al modello e SOLO al modello. Se ti ritrovi a importare istruzioni javax.swing nel Modello, non stai codificando il Modello correttamente.

Il modello quindi imposta il suo stato su "disabilitato" e procede a notificare a tutte le parti interessate questa modifica del modello. The View, essendo interessato a questo evento, si è già registrato come osservatore di eventuali modifiche al modello. Una volta che l'evento di modifica dello stato del modello viene rilevato dalla vista, procede a disabilitare TextField. È inoltre legale che la Vista ottenga informazioni di sola lettura direttamente dal suo Modello senza dover passare attraverso il Controller (di solito attraverso un'interfaccia specifica esposta dal Modello per tale attività)

Promuovendo un tale allentamento tra la presentazione e la logica di business e i livelli di dati, scoprirai che il tuo codice è molto più gestibile. Man mano che i sistemi crescono, anche il tuo approccio a MVC aumenterà. Ad esempio, Hierarchical MVC è un'estensione spesso utilizzata per collegare triadi MVC per formare grandi sistemi a livello aziendale senza accoppiare sottosistemi


0

L'accoppiamento (il tipo che si desidera evitare) comporta un mutuo dipendenza tra due classi. Cioè, un Foo dipende da una barra e una barra dipende da una foo, quindi non puoi davvero modificarne una senza modificare l'altra. È una brutta cosa.

Non puoi davvero evitare di avere ALCUNE dipendenze, tuttavia. Le lezioni devono conoscersi un po 'l'una sull'altra, altrimenti non comunicherebbero mai.

Nel modello MVC, il controller controlla la comunicazione tra il modello di dominio e la vista di presentazione. Pertanto, il Controller deve conoscere abbastanza il Modello per chiedergli di fare ciò che dovrebbe fare. Il controller deve inoltre conoscere abbastanza la vista per poterla presentare al client o agli utenti. Quindi, il Model Controller ha dipendenze da entrambi. Tuttavia, la vista può esistere perfettamente bene senza il controller: non vi è alcuna dipendenza. Allo stesso modo il Modello non ha dipendenze sul controller: è semplicemente quello che è. Infine, il modello e la vista sono completamente separati l'uno dall'altro.

In sostanza, il Controller è il livello di indiretta che disaccoppia la Vista dal Modello, in modo che non debbano conoscersi.


Ah - ecco perché i downvotes - ho sbagliato a scrivere. Intendevo che il controller ha dipendenze da entrambi. D'oh!
Matthew Flynn,

-5

Nella mia esperienza, generalmente il modello dipende solo da una vista, non da una specifica, spesso come osservatore ... se ha un tale accoppiamento.

La vista generalmente si accoppia a qualunque cosa stia guardando, il che ha senso. Difficile trovare una visione che potrebbe essere disaccoppiata da ciò che sta visualizzando ... ma a volte puoi avere un accoppiamento parziale o qualcosa del genere.

Il controller tende spesso ad accoppiarsi con entrambi. Questo ha anche senso poiché il suo compito è trasformare gli eventi di visualizzazione in modifiche al modello.

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

Per capire cos'è MVC e quale tende ad essere la relazione di accoppiamento, dovresti esaminare come è nato MVC. L'ambiente in cui è stato creato MVC era quello in cui non esistevano "widget" come elementi del modulo con cui è possibile creare dialoghi. Una "vista" era una scatola e disegnava cose. Una vista di testo sarebbe una casella che disegna il testo. Una vista elenco era una casella che avrebbe disegnato un elenco. Il "controller" ha ricevuto tutti gli eventi del mouse e della tastiera dal sistema UI che si sono svolti in quella vista; non ci sono stati eventi "textChanged" o "selectionChanged". Il controller prenderebbe tutti questi eventi di basso livello e genererebbe l'interazione con il modello. Il modello, una volta modificato, notificherà le sue opinioni; da allora abbiamo visto questa relazione come "osservatore" ed è "

QUESTA è l'essenza del modello MVC. Dal momento che questo tipo di programmazione dell'interfaccia utente di basso livello non viene più generalmente eseguita, l'MVC si è evoluto in molte direzioni diverse. Alcune cose che portano quel nome oggi non sono affatto come l'MVC e dovrebbero davvero essere chiamate qualcos'altro. Può ancora essere usato 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 MVC doveva risolvere accade ora all'interno dei widget ed è qualcosa che non dobbiamo più usare.


Per quelli che pensano di conoscere meglio:

http://www.codeproject.com/Articles/42830/Model-View-Controller-Model-View-Presenter-and-Mod

http://msdn.microsoft.com/en-us/library/ff649643.aspx

Sono sicuro che ce ne sono altri, ma quelli sono solo in cima all'elenco su Google. Come puoi vedere, il modello dipende molto da un'interfaccia di visualizzazione in MOLTE implementazioni. Generalmente un modello è osservabile e la vista è un osservatore.

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

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

http://martinfowler.com/eaaDev/uiArchs.html

Se la gente vuole continuare a dire che TUTTI nel settore del design hanno torto, allora va bene.


4
Questo è chiaramente sbagliato. Un modello non deve mai dipendere da una vista! Anche se quella vista è astratta o un'interfaccia. Un modello dovrebbe essere completamente disaccoppiato dalla presentazione!
Falcon,

3
La risposta è sbagliata Il modello non dipende da una vista o controller.
CodeART,

2
@Crazy Eddie Hai detto: "Nella mia esperienza, generalmente il modello dipende solo da una vista, non da una specifica, spesso come osservatore" Il tuo riferimento citato dice: "Tuttavia, il modello non dipende né dalla vista né dal controller". Hai mai letto l'articolo citato? Non sembra.
CodeART

2
@Crazy Eddie: non mi interessa cosa scrive qualcuno su un merdoso codeproject. Questo è un design orribile. L'uso di un osservatore per ascoltare le modifiche è ok, ma inserire un'interfaccia di presentazione in un modello di dominio è davvero così sbagliato. Il codice citato dall'articolo è imperfetto in alcuni modi fondamentali rispetto a MVC. Permette persino al modello di dipendere implicitamente dal controller. Che schifezza.
Falcon,

3
@Crazy Eddie: lol @ downvote furia. Ti ho fatto arrabbiare?
Falcon,

-7
  • Il controller invia il modello a una vista ed elabora il modello inviato dalle viste, tuttavia non è strettamente accoppiato a una vista o a un modello.

Se il controller era strettamente associato a una vista, allora saremo in un mondo di moduli web. Avresti un codice dietro il quale sarebbe 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 l'elaborazione delle richieste e l'invio di risposte.

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

  • Il modello non è strettamente accoppiato 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 o controller.

Un altro modo di pensare a questo:

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

  • 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.


1
Questo è così sbagliato che non è divertente. Non vale nemmeno la pena di spiegare. Ignora completamente questa risposta.
Reactgular,

1
@MathewFoscarini Smetti di piangere e lascia una "risposta corretta"
CodeART

2
lol, l'intera teoria del design dietro MVC è che non sono dipendenti l'uno dall'altro.
Reactgular,

Ho lasciato più informazioni per te, si spera abbia senso
CodeART,
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.