Una vista e un modello devono comunicare o no?


33

Secondo la pagina di Wikipedia per l'architettura MVC , la vista è libera di essere notificata dal modello ed è anche libera di interrogare il modello sul suo stato attuale. Tuttavia, secondo il corso Paul Hegarty su iOS 5 a Stanford, lezione 1, pagina 18, tutte le interazioni devono passare attraverso il controller, con Model e View che non dovrebbero mai conoscersi. Non mi è chiaro se la dichiarazione di Hegarty debba essere intesa come una semplificazione del corso, ma sono tentato di dire che intende il design in quanto tale.

Come spieghi questi due punti di vista opposti?

Risposte:


26

Questo è un argomento controverso in MVC / MVVM. Alcuni dicono che è OK per la vista accedere direttamente ai modelli, altri dicono che dovresti avvolgere i modelli in ViewModels per estrarli dalla vista. Personalmente non sono un fan di nessuno dei due approcci.

Uno degli obiettivi principali di MVC / MVVM è il disaccoppiamento dell'interfaccia utente, della logica aziendale e dei dati. Quindi, con questo concetto in mente, consentire alla Vista di accedere direttamente ai Modelli crea una dipendenza che potresti non voler avere. D'altra parte, avvolgere i modelli in ViewModels è spesso noioso e non molto utile poiché i ViewModels tendono ad agire semplicemente come pass-through ai modelli.

Mi piace l'approccio di avere i tuoi modelli implementare una particolare interfaccia, chiamiamolo IModel. La classe ViewModel può quindi offrire istanze di oggetti che implementano IModel per l'utilizzo di View. Il View sa semplicemente che funziona con gli oggetti IModel che ottiene dal ViewModel. Ciò rimuove il codice wrapper ViewModel estraneo e nasconde l'implementazione concreta di IModel dalla vista. In seguito è possibile scambiare un'implementazione di IModel con un'altra senza influire su Visualizza un bit.


1
Per quanto riguarda gli aspetti noiosi della mappatura di un modello su un modello di vista, è necessario notare che sono disponibili strumenti che possono alleviare il dolore della mappatura. Ad esempio: (.NET AutoMapper) (JAVA modelmapper)
Jesse,

+1 Ottima risposta! Questo è un ottimo approccio a seconda della complessità del tuo modello, ma la maggior parte dei modelli oggi sono di tipo Anemico . Elementi del modello, essendo poco più che oggetti dati senza comportamento, vedo poco o nessun bisogno di tale astrazione e poco pericolo nel consentire alla vista di accedere direttamente al modello.
maple_shaft

2
Ho sentito quello che dici; la maggior parte delle interfacce IModel conterrebbe semplicemente un mucchio di dichiarazioni di proprietà e poche (se presenti) dichiarazioni di metodi. Ma anche se i modelli sono anemici, l'interfaccia disaccoppia la vista dalla loro implementazione concreta. Questa separazione potrebbe non essere necessaria per ogni progetto, ma è sempre una buona idea mantenere aperte le opzioni.
Raymond Saltrelli,

1
Sono confuso, se hai un sacco di punti di vista assolutamente diversi, come puoi fare affidamento su un'interfaccia senza ingombrarla? Penso che i modelli di visualizzazione siano fantastici. Crei modelli sufficientemente generici da poter essere utilizzati in tutta l'applicazione e crei modelli di visualizzazione per consumare uno o più modelli e implementare inoltre operazioni che verrebbero utilizzate solo da quella vista.
The Muffin Man,

12

Sul web, tutti chiamano il loro disaccoppiamento MVC.

Alcune tecnologie, come C #, utilizzano MVVM perché non esiste alcun collegamento tra la vista e qualsiasi altra, tutto passa attraverso il localizzatore di servizi, vincolando le variabili.

Su MVC puro, il View parla direttamente con il Modello e viceversa. Il controller è presente solo quando si verificano cambiamenti.

E poi, c'è quello chiamato PAC (Presentation Abstraction Control). In questa architettura, la vista e il modello non parlano tra loro. Il controller è l'unico autorizzato a fare qualsiasi cosa con la vista o il modello. Le persone spesso lo confondono con MVC.

Vedrai una spiegazione molto migliore qui: http://www.garfieldtech.com/blog/mvc-vs-pac


7

Per me, l'obiettivo di base di un'architettura è di non impedire futuri tentativi di refactoring. In genere, le visualizzazioni interagiscono direttamente con i modelli jives con questo requisito ed è relativamente chiaro quando non lo è.

Quando una vista sta diventando troppo intima con un modello, un ViewModel può essere una cosa meravigliosa, ma di solito è il caso per me che i casi in cui è richiesto siano in minoranza.


6

In MVC , Paul Hegarty ha torto. Il controller riguarda gli eventi dell'utente, non la comunicazione da modello a vista. Nel MVC classico , le viste osservano il modello (modello di osservatore).

Con il ragazzo nel mezzo della mediazione, il modello dovrebbe essere chiamato MVP , e in effetti, la maggior parte di ciò che oggi viene presentato come MVC, è in effetti più vicino a MVP.

Poi c'è MVVM che è qualcosa di simile ad entrambi, eppure un po 'diverso, ed è esistito molto tempo fa ... è meglio vederlo come due MVC / MVP legati insieme attraverso l'oggetto viewmodel - il "client" MVC ha viewmodel come il suo modello e il "server" MVC ha come modello il viewmodel.


1
Oggi (inizio 2014), per me (con il mio nodo e stack angolare) questa distinzione su MVC "client" e MVC "server" sembra molto rilevante e in qualche modo illuminante. (grazie)
slacktracer

4

Dal momento che stai chiedendo del materiale in quelle lezioni di Stanford in particolare, vale la pena considerare due cose sulla posizione di Hegarty:

  1. Come hai già detto, sta insegnando un corso di informatica di livello L00. Ci sono molti posti nelle sue lezioni in cui semplifica, lucida sui dettagli o dice "fallo in questo modo", come probabilmente devi fare quando insegni le basi, cioè devi padroneggiare le regole prima di poterle infrangere.
  2. La mia esperienza con iOS SDK è che, laddove non impone una stretta separazione tra View e Model, è fortemente orientato verso quel modello. Quando si scrivono app iOS in particolare, aderire alla separazione vista modello aiuta a scrivere codice in linea con le aspettative del framework. Esiterei a generalizzare le dichiarazioni di Hegarty allo sviluppo su altre piattaforme o in generale.

1

Sono d'accordo con Paul Hegarty e credo che il View non debba conoscere il Modello. Non è così difficile da ottenere, ma porta ulteriori vantaggi al design e alla flessibilità futura.

Nelle piccole applicazioni (di solito desktop) in cui vorrei evitare classi ViewModel "fittizie" e mantenere le cose semplici, utilizzo anche l'interfaccia IModel (vedi la risposta sopra) e faccio attenzione che Model non abbia idea della vista (usa gli abbonati come nel classico MVC).

Anche in questo caso il Controller è diventato abbastanza accoppiato con la Vista e per semplicità non sempre li separo chiaramente.

Il secondo approccio "semplificato" è OK quando si possono avere diverse viste per lo stesso modello, ma non lo consiglierei se si desidera utilizzare la stessa vista per modelli diversi. Sotto diverso intendo davvero diverso per natura e non solo classi di test JUnit che "seguono" il modello principale.


1

Credo che non ci siano regole rigide e veloci per questo, dipende totalmente dalle tue esigenze.

Troverai persone con credenze diverse. Le architetture sono concetti che aiutano a progettare soluzioni migliori.

Oltre alla comunicazione vista modello, c'è un'altra contraddizione sulla logica aziendale in MVC. Molte persone credono che tutta la logica aziendale dovrebbe essere un modello (vedi questa domanda SO ), d'altra parte il collegamento condiviso da Florian (nella sua risposta) dice che la logica aziendale dovrebbe essere sul controller.

Oltre a questo c'è la possibilità di dividere la logica aziendale in Logica applicazione (metterla sul controller) e Login dominio (metterla sul modello).

Quindi, la morale della storia è che MVC significa che modello, vista e controller dovrebbero essere separati. A parte questo, qualunque cosa ti si adatti meglio.


0

Uso DTO per la comunicazione vista modello.

Per esempio:

  • L'utente compila il modulo di aggiornamento (Visualizza)
  • L'utente invia il modulo
  • Il controller associa i dati del modulo a UserUpdateDTO
    • DTO e UserModel sono POJO ma DTO non ha ID e nome utente perché non è possibile aggiornare il nome utente.
    • Un'altra differenza è che la classe Model ha relazioni e associazioni, ma DTO memorizza solo i dati e possiamo aggiungere validatori JSR 303 ad esso
  • Controller lo dice al livello di servizio per salvare
  • Il livello di servizio dice al livello DAO di conservare i dati

-1

Sono con il campo che dice che la vista non dovrebbe mai comunicare con il modello. Il controller deve essere sempre il tipo di riferimento per tutto, quindi decide cosa fare (convalida, richiedi dati dal modello, ecc.).

Tendo a vederlo più come un problema organizzativo che altro.


-1

Come molti sono suggeriti sul perché e come view & model dovrebbero interagire liberamente in contesti diversi, ma il motivo principale in iOS per creare Controller è il mediatore tra loro è evitare le dipendenze di Model & View nella tua base di codice e permettendoci di riutilizzare modello o vista in base ai requisiti con l'evoluzione di iOS.

Poiché potrebbe essere necessario mantenere gli aggiornamenti delle nostre app in UI / UX o Model o alcune volte entrambe, non dovrebbe produrre un codice di dipendenza della modalità tra modello e vista. Se desideri modificare il livello di presentazione della tua app, vai e cambiarlo quindi è ancora possibile riutilizzare lo stesso modello e viceversa può essere fatto.

Anche se sono d'accordo sul fatto che MVC in iOS produca ViewController giganti con molte logiche diverse e gestisca ogni tipo di roba diversa da quella a cui è destinato. Quindi è meglio andare con MVVM o controlli di presentazione per rendere la tua base di codice più flessibile, facile da leggere e gestire con ViewController più piccoli.

Questo potrebbe aiutare chi è alla ricerca di ViewController più piccoli in iOS:

http://blog.xebia.com/simplification-of-ios-view-controllers-mvvm-or-presentation-controls/

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.