Ho usato MVP e MVC in passato e preferisco MVP in quanto controlla il flusso di esecuzione molto meglio secondo me.
Ho creato la mia infrastruttura (classi di archivi dati / repository) e li utilizzo senza problemi durante la codifica dei dati di esempio, quindi ora sto passando alla GUI e sto preparando il mio MVP.
Sezione a
Ho visto MVP usare la vista come punto di ingresso, ovvero nel metodo di costruzione delle viste che crea il presentatore, che a sua volta crea il modello, collegando gli eventi secondo necessità.
Ho anche visto il presentatore come il punto di ingresso, in cui vengono creati una vista, un modello e un presentatore, a questo presentatore viene quindi data una vista e un oggetto modello nel suo costruttore per collegare gli eventi.
Come in 2, ma il modello non viene passato al presentatore. Invece il modello è una classe statica in cui vengono chiamati metodi e le risposte vengono restituite direttamente.
Sezione B
In termini di mantenere la vista e il modello sincronizzati che ho visto.
Ogni volta che un valore nella vista viene modificato, ad es.
TextChanged
Evento in .Net / C #. Questo genera unDataChangedEvent
passaggio nel modello, per mantenerlo sempre sincronizzato. E dove cambia il modello, ovvero un evento in background che ascolta, la vista viene aggiornata con la stessa idea di sollevare aDataChangedEvent
. Quando un utente desidera eseguire il commit delle modifiche,SaveEvent
viene eseguito il passaggio attraverso il modello per eseguire il salvataggio. In questo caso il modello imita le azioni dei dati e dei processi della vista.Simile a # b1, tuttavia la vista non si sincronizza continuamente con il modello. Invece quando l'utente desidera eseguire il commit delle modifiche,
SaveEvent
viene attivato e il relatore acquisisce i dettagli più recenti e li passa nel modello. in questo caso il modello non è a conoscenza dei dati delle viste fino a quando non viene richiesto di agire su di esso, nel qual caso vengono passati tutti i dettagli necessari.
Sezione C
Visualizzazione di oggetti business nella vista, ovvero un oggetto (MyClass) non dati primitivi (int, double)
La vista ha campi proprietà per tutti i suoi dati che verranno visualizzati come oggetti dominio / business. Ad esempio
view.Animals
espone unaIEnumerable<IAnimal>
proprietà, anche se la vista li elabora in nodi in un TreeView. Quindi per l'animale selezionato sarebbe espostoSelectedAnimal
comeIAnimal
proprietà.La vista non è a conoscenza di oggetti di dominio, espone la proprietà solo per i tipi di oggetti inclusi primitivo / framework (.Net / Java). In questo caso il presentatore passerà un oggetto adattatore l'oggetto di dominio, l'adattatore quindi tradurrà un determinato oggetto business nei controlli visibili nella vista. In questo caso l'adattatore deve avere accesso ai controlli effettivi sulla vista, non a qualsiasi vista, quindi diventa più strettamente accoppiato.
Sezione D
Visualizzazioni multiple utilizzate per creare un singolo controllo. cioè hai una vista complessa con un modello semplice come salvare oggetti di diversi tipi. Potresti avere un sistema di menu sul lato con ogni clic su un elemento che mostra i controlli appropriati.
Si crea una vista enorme, che contiene tutti i singoli controlli che sono esposti tramite l'interfaccia viste.
Hai diverse visualizzazioni. Hai una vista per il menu e un pannello vuoto. Questa vista crea le altre viste richieste ma non le visualizza (visibile = falso), inoltre implementa l'interfaccia per ogni vista che contiene (cioè le viste figlio) in modo che possa essere esposta a un relatore. Il pannello vuoto è riempito con altre viste (
Controls.Add(myview)
) e ((myview.visible = true
). Gli eventi generati in queste viste "figlio" sono gestiti dalla vista padre che a sua volta passa l'evento al presentatore, e viceversa per fornire eventi indietro agli elementi figlio.Ogni vista, che si tratti del genitore principale o delle viste figlio minore, è collegata al proprio presentatore e modello. Puoi letteralmente rilasciare un controllo di visualizzazione in un modulo esistente e avrà la funzionalità pronta, basta un cablaggio in un presentatore dietro le quinte.
Sezione E
Se tutto avesse un'interfaccia, ora in base al modo in cui l'MVP viene eseguito negli esempi precedenti, questa risposta influirà in quanto potrebbe non essere compatibile con la compatibilità incrociata.
Tutto ha un'interfaccia, il View, Presenter e Model. Ognuno di questi ha quindi ovviamente un'implementazione concreta. Anche se hai solo una visione concreta, un modello e un presentatore.
La vista e il modello hanno un'interfaccia. Ciò consente alle viste e ai modelli di differire. Il presentatore crea / riceve oggetti vista e modello e serve solo a passare messaggi tra di loro.
Solo la vista ha un'interfaccia. Il modello ha metodi statici e non viene creato, quindi non è necessaria un'interfaccia. Se si desidera un modello diverso, il presentatore chiama un diverso set di metodi di classe statici. Essendo statico, il Modello non ha alcun link al presentatore.
Pensieri personali
Di tutte le diverse varianti che ho presentato (la maggior parte che ho probabilmente usato in qualche forma) di cui sono sicuro che ce ne siano altre. Preferisco A3 come mantenere la logica aziendale riutilizzabile al di fuori del solo MVP, B2 per ridurre la duplicazione dei dati e meno eventi. C1 per non aggiungere in un'altra classe, sicuro che mette una piccola quantità di logica non unit testabile in una vista (come viene visualizzato un oggetto di dominio) ma questo potrebbe essere rivisto dal codice o semplicemente visualizzato nell'applicazione. Se la logica fosse complessa, accetterei una classe adattatore ma non in tutti i casi. Per la sezione D, penso che D1 crei una vista troppo grande per un esempio di menu. Ho usato D2 e D3 prima. Il problema con D2 è che devi scrivere un sacco di codice per indirizzare gli eventi da e verso il presentatore alla vista figlio corretta e non è compatibile con il trascinamento / rilascio, ogni nuovo controllo necessita di più collegamenti per supportare il singolo presentatore. D3 è la mia scelta preferita, ma aggiunge ancora più classi come presentatori e modelli per gestire la vista, anche se la vista sembra essere molto semplice o non ha bisogno di essere riutilizzata. penso che una miscela di D2 e D3 sia meglio basata sulle circostanze. Per quanto riguarda la sezione E, penso che tutto ciò che ha un'interfaccia potrebbe essere eccessivo, lo faccio già per oggetti di dominio / business e spesso non vedo alcun vantaggio nella "progettazione", ma aiuta a deridere gli oggetti nei test. Personalmente vedrei l'E2 come una soluzione classica, sebbene abbia visto l'E3 usato in 2 progetti su cui ho lavorato in precedenza. penso che una miscela di D2 e D3 sia meglio basata sulle circostanze. Per quanto riguarda la sezione E, penso che tutto ciò che ha un'interfaccia potrebbe essere eccessivo, lo faccio già per oggetti di dominio / business e spesso non vedo alcun vantaggio nella "progettazione", ma aiuta a deridere gli oggetti nei test. Personalmente vedrei l'E2 come una soluzione classica, sebbene abbia visto l'E3 usato in 2 progetti su cui ho lavorato in precedenza. penso che una miscela di D2 e D3 sia meglio basata sulle circostanze. Per quanto riguarda la sezione E, penso che tutto ciò che ha un'interfaccia potrebbe essere eccessivo, lo faccio già per oggetti di dominio / business e spesso non vedo alcun vantaggio nella "progettazione", ma aiuta a deridere gli oggetti nei test. Personalmente vedrei l'E2 come una soluzione classica, sebbene abbia visto l'E3 usato in 2 progetti su cui ho lavorato in precedenza.
Domanda
Sto implementando correttamente MVP? C'è un modo giusto di farlo?
Ho letto il lavoro di Martin Fowler che ha delle variazioni e ricordo che quando ho iniziato a fare MVC, ho capito il concetto, ma in origine non sono riuscito a capire dove si trova il punto di ingresso, tutto ha una sua funzione ma ciò che controlla e crea l'originale insieme di oggetti MVC.