Domanda

Mi sto divertendo un po 'a cercare di capire come funziona MVP, per quanto riguarda i controlli utente. Sto usando .NET WinForms (o qualcosa di simile) e Supervision Controller pattern (beh, penso di essere :).

Il controllo utente è esso stesso parte di un'applicazione MVP (è la vista e ha un presentatore associato, ecc.). Il Presenter viene sempre avviato per primo e avvia il / i modello / i e quindi le viste. La vista crea la sua interfaccia utente, parte della quale sarà NUOVA UC, che è la vista.

Ora il (modulo) Presenter deve conoscere UC Presenter, ma sto pensando che non sappia nulla su come è composta la vista. Il presentatore del modulo, ad esempio, non sa che l'UC fa parte della raccolta Controls del modulo, né dovrebbe.

Inoltre, l'esperienza di progettazione non dovrebbe essere modificata; IOW lo sviluppatore della vista (modulo) dovrebbe essere in grado di selezionare un controllo utente dalla casella degli strumenti e rilasciarlo su un modulo.

Quindi, alle mie domande. In primo luogo, le mie ipotesi sopra sono corrette? Un po 'fuorviato? Incasinato? Cosa stai pensando?

In secondo luogo, è giusto (abbastanza?) che il modulo View invochi la vista UC, e il modulo Presenter invochi il UC Presenter e disponga di un meccanismo per dire alla UC View qual è il suo presentatore? Questo rompe il mio "presentatore prima" regola, ma non sono sicuro di come altro farlo.

Qualsiasi altro pensiero, suggerimento, commento accettato volentieri.

- nwahmaet

È stato utile?

Soluzione

Un relatore dovrebbe essere considerato come "stato autonomo" nel livello di presentazione. Ciò significa che è responsabile di garantire che la presentazione della vista dello stato del modello sia sincronizzata. Il motivo per cui lo sollevo è perché il "pattern" di MVP spesso si perde nella visione dogmatica di come le cose dovrebbero essere separate. Sembra che questo sia uno dei motivi per cui Martin Fowler ha deciso di provare a chiarire la terminologia attorno al modello MVP .

Il mio sapore preferito di MVP è la vista passiva , quindi la mia risposta si basa su questo .

Implemento controlli e moduli utente compositi molto spesso usando il modello di vista passiva. Esistono essenzialmente 3 diverse configurazioni:

  1. Un presentatore per tutti i controlli utente nella gerarchia. Appiattire la vista utilizzando un'interfaccia.
  2. Un relatore per ciascun controllo utente nella struttura ad albero composito. Ogni relatore principale è responsabile dell'istanza e dell'inizializzazione dei relatori secondari. I controlli utente vengono creati in fase di progettazione e sono in grado di funzionare senza un relatore (senza comportamento di presentazione)
  3. Un relatore per ciascun controllo utente nella struttura ad albero composito. Tutti i presentatori sono accoppiati liberamente attraverso una classe di controller di livello superiore. La classe controller è responsabile della costruzione del presentatore, del cablaggio e del coordinamento dei loro eventi.

Sebbene sia una soluzione di ultima istanza per me (a causa della sua complessità), penso che l'ultima opzione sia la soluzione che stai cercando.

Altri suggerimenti

Mi sono imbattuto in questo esatto problema per diversi mesi in un'applicazione a cui sto lavorando. La conclusione a cui sono giunto molto recentemente è che in molti casi potrebbe essere impossibile applicare il modello MVP sia a livello di finestra che a livello di controllo utente, senza "rompere". il modello.

Il mio pensiero è che il controllo utente fa parte dell'implementazione della vista e il relatore non dovrebbe sapere cosa sta succedendo all'interno dell'implementazione della vista, il che significa che il presentatore a livello di finestra per estensione non dovrebbe conoscere l'utente il presentatore di controllo, e quindi non dovrebbe esserci comunicazione tra di loro, inclusa l'istanza di quest'ultimo da parte del primo. Si potrebbe obiettare che il relatore del controllo utente fa parte dell'implementazione della vista della finestra e quindi la vista della finestra può creare un'istanza del relatore del controllo utente. Ma non può iniettare le classi del modello di cui il relatore ha bisogno, perché la vista non dovrebbe esserne consapevole.

La conclusione a cui penso di arrivare è che TUTTI i controlli utente sono specifici dell'implementazione della vista e quindi dovrebbero essere contenuti completamente nel silo della vista del modello più grande. Come tali, non possono avere i loro presentatori ... Almeno non in bundle con l'implementazione del controllo stesso. Dovrebbero invece essere manipolati indirettamente dal presentatore della finestra principale, tramite campi pass-through esposti sull'interfaccia della vista. In breve, il controllo utente è esposto al presentatore non dalla sua stessa interfaccia, ma piuttosto attraverso un'interfaccia pass-through comune implementata dalla sua vista padre. Chiamalo "interfaccia a vista parziale".

Il relatore può quindi contenere istanze di una classe di sub-presentatore riutilizzabile che funziona solo con questa interfaccia di vista parziale e i relativi pezzi del modello. Ciò consentirà di evitare di riscrivere il codice del presentatore da tradurre dal modello ogni volta che è necessario utilizzare il controllo, E impedisce alla vista della finestra di dover conoscere il modello per passare le informazioni al presentatore del controllo.

Ciò che effettivamente fa è che separa ulteriormente il controllo utente, come modulo, dal tuo modello di dati. Ciò ha senso se si considera un controllo utente, nel suo insieme, come un elemento dell'implementazione della vista. Come unità riutilizzabile, è una funzionalità pezzo di vista e nessuna parte di essa dovrebbe essere legata al tuo modello di dati.

Le tue domande sono generali che potrebbero essere applicate una varietà di schemi.

In questo caso, suppongo che dovresti guardare Observer Pattern.

Hai un'interfaccia che qualsiasi cosa utilizzi quella vista implementerebbe. Quindi si registra automaticamente quando l'applicazione si inizializza con una raccolta di tali interfacce. Qualsiasi comando che deve aggiornare quella vista attraverserebbe la raccolta notificando che ogni vista dovrebbe essere aggiornata.

A differenza degli esempi tipici, le viste sarebbero Controlli utente. Hai la flessibilità di far implementare tale interfaccia a qualsiasi elemento dell'interfaccia utente in modo da poter utilizzare finestre di dialogo, moduli completi, ecc. Oltre al controllo utente.

Infine, ricorda che il Controllo utente NON è la vista ma l'implementazione della Vista. Qualunque schema tu adotti, puoi definire ciò che la vista è profonda quanto vuoi e far sì che il controllo utente implementi tale interfaccia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top