La "C" di MVC è davvero necessaria?

37

Comprendo il ruolo del modello e della vista nel modello Model-View-Controller, ma ho difficoltà a capire perché è necessario un controller.

Supponiamo di creare un programma di scacchi usando un approccio MVC; lo stato del gioco dovrebbe essere il modello e la GUI dovrebbe essere la vista. Che cosa è esattamente il controller in questo caso?

È solo una classe separata che ha tutte le funzioni che verranno chiamate quando, per esempio, fai clic su una tessera? Perché non basta eseguire tutta la logica sul modello nella vista stessa?

    
posta Anne Nonimus 28.03.2012 - 00:27
fonte

11 risposte

4

Usando il tuo esempio, il controllore sarebbe stato ciò che ha deciso quale fosse una mossa legale o meno. Il Controller lascia che la vista sappia come organizzare i pezzi alla lavagna all'avvio usando le informazioni ricevute dal Modello. Ci sono più cose che possono essere gestite dal Controller, ma la chiave è pensare a Business Logic su quel livello.

Ci sono momenti in cui tutto il controller fa passare le informazioni avanti e indietro, come una pagina di registrazione. Altre volte il Controller è la parte difficile dello sviluppo perché ci sono molte cose che devono essere fatte a quel livello, come ad esempio far rispettare le regole o fare matematica complicata. Non dimenticare il controller!

    
risposta data 28.03.2012 - 00:46
fonte
39

Why not just perform all the logic on the model in the view itself?

Il controller è la colla che lega il modello e la vista insieme, ed è anche l'isolamento che li tiene separati. Il modello non dovrebbe sapere nulla della vista e viceversa (almeno nella versione Apple di MVC). Il controller agisce come un adattatore bidirezionale, traducendo le azioni dell'utente dalla vista in messaggi al modello e configurando la vista con i dati del modello.

L'utilizzo del controller per separare il modello e la vista rende il codice più riutilizzabile, più verificabile e più flessibile. Considera il tuo esempio di scacchi. Il modello includerebbe naturalmente lo stato del gioco, ma potrebbe anche contenere la logica che influenza le modifiche allo stato del gioco, come determinare se una mossa è legale e decidere quando il gioco è finito. La visualizzazione mostra una scacchiera e pezzi e invia messaggi quando un pezzo si muove, ma non sa nulla del significato dietro i pezzi, come si muove ogni pezzo, ecc. Il controller conosce sia il modello e la vista, nonché il flusso generale del programma. Quando l'utente preme il pulsante "nuovo gioco", è un controller che indica al modello di creare un gioco e utilizza lo stato del nuovo gioco per impostare il tabellone. Se l'utente fa una mossa, il controllore trasmette il comando al modello e, in base alla risposta, consente lo spostamento o meno.

Guarda cosa ottieni mantenendo il modello e la vista separati:

  • È possibile modificare il modello o la vista senza modificare l'altro. Potrebbe essere necessario aggiornare il controller quando si modifica uno dei due, ma in un modo questo è parte del vantaggio: le parti del programma che sono più probabili cambiare sono concentrate nel controller.

  • Modello e vista possono essere riutilizzati. Ad esempio, è possibile utilizzare la stessa vista scacchiera con un feed RSS come modello per illustrare giochi famosi. In alternativa, è possibile utilizzare lo stesso modello e sostituire la vista con un'interfaccia basata sul Web.

  • È facile scrivere test per modello e vista per garantire che funzionino come dovrebbero.

  • Sia il modello che la vista possono spesso trarre vantaggio dalle parti standard: matrici, mappe, insiemi, stringhe e altri contenitori di dati per il modello; pulsanti, controlli, campi di testo, visualizzazioni di immagini, tabelle e altri per la vista.

risposta data 28.03.2012 - 05:11
fonte
7

Ci sono molti, molti modi diversi per implementare questo schema generale di progettazione, ma l'idea di base è di separare le varie preoccupazioni come necessario. MVC è una bella astrazione nel senso che:

Modello : rappresenta quei dati, qualunque cosa ciò possa significare
Visualizza : rappresenta l'interfaccia utente, qualunque cosa ciò possa significare il Controller : rappresenta la colla che fa sì che quel modello e la vista interagiscano, qualunque cosa possa significare

È estremamente flessibile perché non specifica un intero lotto. Un sacco di gente spreca molta larghezza di banda discutendo i dettagli di ciò che ciascun elemento potrebbe significare, quali nomi dovrebbero essere usati al posto di questi e se ci dovrebbero essere davvero 3 o 2 o 4 o 5 componenti, ma questo non ha senso certo grado.

L'idea è di separare i diversi "pezzi" della logica in modo che non si sovrappongano. Mantieni insieme le tue presentazioni, tieni insieme i tuoi dati, mantieni le tue cose logiche insieme, mantieni le tue cose di comunicazione insieme. E così via. In una certa misura, meno queste aree di preoccupazione si sovrappongono, più è facile fare cose interessanti con loro.

Questo è tutto ciò di cui dovresti davvero preoccuparti.

    
risposta data 28.03.2012 - 06:56
fonte
4

Tutte le buone risposte finora. I miei due centesimi sono che mi piace pensare che il controller sia principalmente costituito da domande come Cosa e dove?

  • Mi è stato chiesto se un pezzo degli scacchi (vista) può essere spostato su x. È
    permesso? Non sono sicuro, ma so dove e chi chiedere (il modello).
  • Qualcosa mi ha chiesto di salvare i miei dati. Come diavolo lo faccio? So però dove chiederlo! Come salviamo i dati, o dove sono salvati, Non ne ho idea, ma quella classe Repository dovrebbe saperlo. Lo inoltrerò e lascerò che si occupi di esso.
  • Devo mostrare all'utente la posizione attuale del pezzo degli scacchi il modello lo ha spostato in. non sono sicuro se voglio mostrare il pezzo come verde o giallo? Bah, a chi importa, so che c'è una visione che può gestire così passerò i dati e loro potranno decidere come stanno andando essere mostrato.

Questi piccoli frammenti sono esempi di come sto cercando di ricordare l'astrazione e il concetto che MVC sta cercando di trasmettere. Cosa, dove e come sono i miei tre principali processi di pensiero.

Cosa e dove = > controllore Come e quando = > Modelli e viste

In sostanza le azioni del mio controllore tendono ad essere piccole e compatte e quando le leggi tendono a sembrare a volte una perdita di tempo. A ben guardare, agiscono come l'uomo del segnale stradale, convogliando le varie richieste ai lavoratori appropriati, ma non facendo loro alcuno dei lavori stessi.

    
risposta data 28.03.2012 - 09:28
fonte
2

Un controller può aiutare ad astrarre le interfacce della vista e del modello in modo che non debbano sapere l'uno sull'altro direttamente. Meno un oggetto deve sapere, più diventa portatile e controllabile.

Ad esempio, il Modello potrebbe giocare un'altra istanza di se stesso attraverso un Controller. O un controller in rete potrebbe collegare insieme gli oggetti Views di due giocatori. Oppure potrebbe essere un test di Turing in cui nessuno sa quale.

    
risposta data 28.03.2012 - 04:54
fonte
2

Entra davvero in gioco quando hai a che fare con i gestori di eventi, ma hai ancora bisogno del controller per gestire le interazioni tra la vista e il modello. Idealmente non vuoi che la vista sappia qualcosa sul modello. Pensaci, vuoi un jsp per fare tutte le chiamate al database direttamente? (A meno che non si tratti di una ricerca di accesso.) Si desidera che la vista esegua il rendering dei dati e non abbia alcuna logica di business, a meno che non sia la logica di rendering della vista, ma non la logica aziendale.

In GWT, ottieni una separazione più pulita con MVP. Non c'è alcuna logica di business (se è fatta bene) nella vista. Il relatore funge da controller e la vista non ha alcuna conoscenza del modello. I dati del modello vengono semplicemente passati alla vista.

    
risposta data 28.03.2012 - 00:38
fonte
1

Vista documento (cioè vista modello) è il modello standard per la maggior parte delle app Windows scritte in MFC, quindi deve funzionare per molti casi.

    
risposta data 23.08.2012 - 01:38
fonte
1

I understand the role of the model and view in the Model-View-Controller pattern, but I have a hard time understanding why a controller is necessary.

Ne sei sicuro? (Almeno come originariamente descritto) Il punto del modello deve essere il modello di dominio. La vista dovrebbe visualizzare il modello di dominio per l'utente. Si suppone che il controllore esegua il mapping di input di basso livello a modelli di alto livello. Per quanto posso dire il ragionamento è qualcosa del tipo: A) un uso di alto livello dell'SRP. B) Il modello è stato considerato la parte più importante dell'app, quindi tieni da parte il materiale meno importante e più veloce. C) logica di business facilmente testabile (e soggetta a script).

Pensa solo se vuoi rendere il tuo programma di scacchi utilizzabile dai non vedenti, scambia la vista con una versione udibile e un controller che funziona con la tastiera. Supponiamo che tu voglia aggiungere giochi per posta, aggiungere un controller che accetti il testo. Versione Net del gioco? Un controller che accetta i comandi da un socket farebbe il lavoro. Aggiungi un bel rendering 3D ad esso, una nuova fantastica vista. Niente cambi di modello necessari Gli scacchi sono ancora scacchi.

Se mischi l'input con la rappresentazione del modello, perdi quell'abilità. Improvvisamente, gli scacchi non sono scacchi, sono gli scacchi con un mouse che è diverso dagli scacchi con una tastiera o una connessione di rete.

    
risposta data 23.08.2012 - 17:37
fonte
0

Penso che MVC sia stupido, forse in aree specifiche funziona bene, ma personalmente anche i siti web che scrivo non sono adatti a mvc. C'è una ragione per cui si sente frontend, backend e mai database-end o qualcosa-else-end

IMO ci dovrebbe essere un'API (back-end) e l'app che usa l'API (frontend). Suppongo che tu possa chiamare la richiesta GET al controller (che chiama semplicemente l'API backend) e la vista HTML, ma di solito non sento persone parlare di view come puro html né di modello come API back-end.

Tutto IMO dovrebbe essere un'API solida. In realtà non hanno bisogno di essere solidi (come quelli puliti e ben costruiti), ma i loro interni dovrebbero rimanere privati e l'app / frontend / all'esterno dell'API non dovrebbe mai dire la connessione al database, né essere in grado di fare query non elaborate.

Ora se il tuo codice / design coinvolge la colla va bene. Se nel tuo gioco degli scacchi ci sono dei markup che puoi modificare per colorare la GUI, la GUI raccoglie i coords / input e chiama MovePiece (srcPosition, dstPostion) (che può restituire un bool o enum per dire se è una mossa valida o no ) e il tuo ok con tutta la logica che si trova nel modello, quindi sicuro chiamalo MVC. Tuttavia, organizzerei comunque le cose in base alle classi e alle API e ci assicurerei che non esistesse una classe per i piatti da cucina che tocchi tutto (né alcuna API da sapere su tutto).

    
risposta data 23.08.2012 - 04:31
fonte
0

Pensa a un browser che visualizza una pagina Web statica. Il modello è l'HTML. La vista è il risultato reale sullo schermo.

Ora aggiungi qualche JavaScript. Questo è il controller. Quando l'utente fa clic su un pulsante o trascina qualcosa l'evento viene inviato al codice JavaScript, decide cosa fare e modifica l'HTML sottostante (modello) e il browser / renderizzatore visualizza tali modifiche sullo schermo (Visualizza).

Forse si fa clic su un altro pulsante, l'evento viene inviato a un gestore (Controller) e può causare la richiesta di ulteriori dati da inviare a un servizio web. Il risultato viene quindi aggiunto all'HTML (Modello).

Il controllore risponde agli eventi e controlla cosa si trova nel modello e quindi cosa c'è sullo schermo / vista.

Facendo un passo indietro, puoi pensare all'intero browser come a Vista e al server come a Controller e ai dati come a Modello. Quando l'utente fa clic su un pulsante nel browser l'evento inviato al server (Controller), raccoglie le risorse come una pagina HTML (Modello) e le invia di nuovo al browser per visualizzarle (Visualizza)

Giù nel server se è asp, php o java il 'codice' (Controller) riceve l'evento click e interroga un database o un repository di documenti (Modello) e crea HTML. Dal punto di vista del server, il risultato di tutte le sue azioni è una vista (HTML) del suo datastore sottostante (modello). Ma dal punto di vista del cliente il risultato della sua richiesta al server è il suo modello (HTML)

Anche se incasini il tuo JavaScript nel tuo HTML o il tuo PHP nel tuo codice HTML, il Modello, Visualizza, Controller esiste ancora. Anche se pensi alla tua richiesta di un server e alla risposta del server come a una strada a doppio senso, c'è ancora un modello, una vista e un controller.

    
risposta data 24.03.2013 - 22:16
fonte
-2

In base alla mia esperienza, in un tradizionale programma di gui di mvc per desktop, il controller finisce per impolverarsi nella vista. La maggior parte delle persone non impiega il tempo a calcolare una classe di controller.

il libro della gang-of-four dice:

Design Patterns in Smalltalk MVC

The Model/View/Controller (MVC) triad of classes [KP88] is used to build user interfaces in Smalltalk-80. Looking at the design patterns inside MVC should help you see what we mean by the term "pattern."

MVC consists of three kinds of objects. The Model is the application object, the View is its screen presentation, and the Controller defines the way the user interface reacts to user input. Before MVC, user interface designs tended to lump these objects together. MVC decouples them to increase flexibility and reuse.

MVC decouples views and models by establishing a subscribe/notify protocol between them. A view must ensure that its appearance reflects the state of the model. Whenever the model's data changes, the model notifies views that depend on it. In response, each view gets an opportunity to update itself. This approach lets you attach multiple views to a model to provide different presentations. You can also create new views for a model without rewriting it.

The following diagram shows a model and three views. (We've left out the controllers for simplicity.) The model contains some data values, and the views defining a spreadsheet, histogram, and pie chart display these data in various ways. The model communicates with its views when its values change, and the views communicate with the model to access these values.

Taken at face value, this example reflects a design that decouples views from models. But the design is applicable to a more general problem: decoupling objects so that changes to one can affect any number of others without requiring the changed object to know details of the others. This more general design is described by the Observer (page 293) design pattern.

Another feature of MVC is that views can be nested. For example, a control panel of buttons might be implemented as a complex view containing nested button views. The user interface for an object inspector can consist of nested views that may be reused in a debugger. MVC supports nested views with the CompositeView class, a subclass of View. CompositeView objects act just like View objects; a composite view can be used wherever a view can be used, but it also contains and manages nested views.

Again, we could think of this as a design that lets us treat a composite view just like we treat one of its components. But the design is applicable to a more general problem, which occurs whenever we want to group objects and treat the group like an individual object. This more general design is described by the Composite (163) design pattern. It lets you create a class hierarchy in which some subclasses define primitive objects (e.g., Button) and other classes define composite objects (CompositeView) that assemble the primitives into more complex objects.

MVC also lets you change the way a view responds to user input without changing its visual presentation. You might want to change the way it responds to the keyboard, for example, or have it use a pop-up menu instead of command keys. MVC encapsulates the response mechanism in a Controller object. There is a class hierarchy of controllers, making it easy to create a new controller as a variation on an existing one.

A view uses an instance of a Controller subclass to implement a particular response strategy; to implement a different strategy, simply replace the instance with a different kind of controller. It's even possible to change a view's controller at run-time to let the view change the way it responds to user input. For example, a view can be disabled so that it doesn't accept input simply by giving it a controller that ignores input events.

The View-Controller relationship is an example of the Strategy (315) design pattern. A Strategy is an object that represents an algorithm. It's useful when you want to replace the algorithm either statically or dynamically, when you have a lot of variants of the algorithm, or when the algorithm has complex data structures that you want to encapsulate.

MVC uses other design patterns, such as Factory Method (107) to specify the default controller class for a view and Decorator (175) to add scrolling to a view. But the main relationships in MVC are given by the Observer, Composite, and Strategy design patterns.

    
risposta data 24.03.2013 - 23:32
fonte

Leggi altre domande sui tag