Vista gerarchica / ViewModel / Presenters in MVPVM

4

Lavoro con MVVM da un po ', ma di recente ho iniziato a utilizzare MVPVM e voglio sapere come creare l'applicazione View / ViewModel / Presenter gerarchica usando questo modello.

In MVVM tipicamente creerei la mia applicazione utilizzando una gerarchia di viste e corrispondenti ViewModels, ad es. Potrei definire 3 visualizzazioni come segue:

Imodellidivistaperquestevistesarebberoiseguenti:

publicclassAViewModel{publicstringText{get{return"This is A!"; }
    }

    public object Child1 { get; set; }    
    public object Child2 { get; set; }
}

public class BViewModel
{
    public string Text
    {
        get { return "This is B!"; }
    }
}

public class CViewModel
{
    public string Text
    {
        get { return "This is C!"; }
    }
}

In avrebbe quindi alcuni modelli di dati per dire che BViewModel e CViewModel dovrebbero essere presentati usando View B e View C:

<DataTemplate DataType="{StaticResource local:BViewModel}">
    <local:BView/>
</DataTemplate>
<DataTemplate DataType="{StaticResource local:CViewModel}">
    <local:CView/>
</DataTemplate>

Il passaggio finale sarebbe inserire un codice in AViewModel che assegnerebbe valori a Child1 e Child2:

public AViewModel()
{
    this.Child1 = new AViewModel();
    this.Child2 = new BViewModel();
}

Il risultato di tutto questo sarebbe uno schermo simile a questo:

Fare questo in MVPVM sarebbe abbastanza semplice - semplicemente spostando il codice nel costruttore di AViewModel in APresenter:

public class APresenter 
{
    ....
    public void WireUp()
    {
        ViewModel.Child1 = new BViewModel();
        ViewModel.Child2 = new CViewModel();
     } 
}

Ma se voglio avere una logica di business per BViewModel e CViewModel dovrei avere un BPresenter e un CPresenter - il problema è, non sono sicuro di dove sia il posto migliore per metterli.

Potrei memorizzare riferimenti al presentatore per AViewModel.Child1 e AViewModel.Child2 in APresenter i.e.:

public class APresenter : IPresenter
{
    private IPresenter child1Presenter;
    private IPresenter child2Presenter;

    public void WireUp()
    {
        child1Presenter = new BPresenter();
        child1Presenter.WireUp();
        child2Presenter = new CPresenter();
        child2Presenter.WireUp();

        ViewModel.Child1 = child1Presenter.ViewModel;
        ViewModel.Child2 = child2Presenter.ViewModel;
    }
}

Ma questa soluzione sembra inelegante rispetto all'approccio MVVM. Devo tenere traccia sia del relatore che del modello di visualizzazione e assicurare che rimangano sincronizzati. Se, ad esempio, volevo un pulsante nella vista A, che, quando si faceva clic su Vista in Child1 e Child2, potevo avere un comando che eseguiva le seguenti operazioni:

var temp = ViewModel.Child1;
ViewModel.Child1 = ViewModel.Child2;
ViewModel.Child2 = temp;

Questo funzionerebbe fino a scambiare la vista sullo schermo (supponendo che sia presente il corretto codice di notifica di modifica proprietà), ma ora il mio APresenter.child1Presenter punta al presentatore per AViewModel.Child2 e APresenter.child2Presenter punta a il presentatore per AViewModel.Child1. Se qualcosa accede a APresenter.child1Presenter, qualsiasi modifica verrà effettivamente eseguita in AViewModel.Child2. Posso immaginare questo che porta a tutti i tipi di divertimento di debug.

So che potrei fraintendere il modello, e se questo è il caso, sarà apprezzato un chiarimento su ciò che sto facendo.

EDIT : questa domanda riguarda WPF e il modello di progettazione MVPVM, non ASP.NET e MVP.

    
posta Brian Flynn 23.11.2012 - 10:20
fonte

2 risposte

2

Quindi penso che tu abbia qualche piccola violazione di MVVM | Pattern MVPVM a causa del collegamento che stai creando tra le visualizzazioni. Tuttavia, nessuno dei due pattern è così dettagliato rispetto alle finestre figlio, quindi è un po 'oscuro.

Penso che valga la pena sottolineare che il grande vantaggio di MVPVM rispetto a MVVM è dovuto alla separazione della logica di business. La VM diventa un contenitore di dati e la P gestisce la logica più l'accesso DAL. L'articolo di Bill Kratochvil su MVPVM è stato un'ottima lettura.

Bill fa un commento riguardante le finestre secondarie e riuso che penso sia adatto:
In cases where a Presenter can be reused across enterprise applications, it’s likely a module would be better suited for the task—that is, you could create a login module (project) that could be reused by all of your enterprise applications.

Che tipo di rinforzo che ti trovi in un territorio oscuro con due componenti figlio.

Indipendentemente da MVVM o MVPVM, penso che avresti bisogno di entrambi

  • B-VM e C-VM quando si utilizza MVVM
  • B-P e C-P e B-VM e C-VM quando si utilizza MVPVM

perché sono funzionalmente separati da A. Se non sono funzionalmente separati, allora perché hanno bisogno delle loro Views?

Penso che le sfide che si presentano con lo scambio di ViewB e ViewC è dovuto al fatto che c'è una certa sfocatura tra proprietà dell'oggetto e responsabilità. Questo è in realtà solo un altro modo di chiedere se B e C sono funzionalmente separati da A o meno. Se lo sono, quindi rendili in questo modo e in caso contrario, non impostarli come indipendenti.

Per materiale leggero senza molta logica aziendale che potrebbe essere riutilizzato, penso che MVPVM sia più impegnativo di quanto valga con MVVM. Questa è chiaramente una generalità e la logica di business della tua applicazione potrebbe prestarsi ad essere espressa in modo più elegante con MVPVM. Basandomi sulla tua domanda, sembra che MVVM possa essere sufficiente per ciò di cui hai bisogno.

    
risposta data 28.11.2012 - 18:53
fonte
0

Se stai scambiando il ViewModel, non dovresti scambiare anche il relatore?

Comunque, ho fatto ricerche sul pattern MVP. Sono lontano dalla comprensione. Ma posso darti alcuni link che mi stanno aiutando:

link

link

Alla fine, non esiste un modo corretto di implementarlo. Ho letto da qualche parte che se metti 10 programmatori in una stanza che discutono di MVP, avrai 11 diverse implementazioni. Dovresti fare tutto ciò che è meglio per te.

Se non mi sbaglio, questi schemi sono lì per aiutare a separare le preoccupazioni e anche a testare il codice. Prova le varianti e scopri cosa funziona meglio per te.

    
risposta data 29.11.2012 - 04:44
fonte

Leggi altre domande sui tag