È necessario aggiungere un livello aggiuntivo tra il modello di dominio e il modello di visualizzazione?

0

Sto lavorando su un'applicazione Xamarin (Mvvm usando Prism), sto anche sfruttando OData per la comunicazione tra il mio back-end e l'applicazione mobile.

La struttura della mia app per dispositivi mobili è la seguente:

  • Visualizza
  • Visualizza il modello
  • Livello di servizio
  • Proxy OData per restituire i modelli

È un po 'strano con OData perché i miei modelli di dominio / DTO sono gli stessi e finisco per esporli direttamente al livello View, tuttavia io sono l'unico sviluppatore e l'astrazione più complessa sarebbe ingombrante da mantenere ... Almeno quello è stato il mio pensiero fino a questo punto. Ora mi trovo di fronte a una situazione in cui devo eseguire una logica aggiuntiva sull'oggetto Model prima del livello di presentazione:

L'esempio del modello ( MyComplexModel ) di OData assomiglia a questo:

public class MyComplexModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<MyComplexModelFeedback> Feedback { get; set; }
}

public class MyComplexModelFeedback
{
    public int Id { get; set;}
    public int PersonId { get; set; }
    public int Vote { get; set; }
}

Solitamente vorrei solo Bind della vista direttamente a MyComplexModel e presentarlo tramite un ListView , ma ora voglio appiattirlo / sommare la proprietà Vote prima di presentarti. È appropriato mappare questo oggetto a un nuovo oggetto direttamente nel mio ViewModel?

Oppure ho pensato di aggiungere un modello di facciata per i miei modelli di visualizzazione da usare / esporre, che mapperei nel livello di servizio, tuttavia il mio codice base aumenterebbe del > 30% ... C'è un modo semplice per aggirare questo problema o questo è un sintomo di un problema di progettazione più grande?

    
posta S1r-Lanzelot 07.06.2018 - 15:21
fonte

1 risposta

1

Ci sono un paio di cose che vorresti porre rimedio:

  • Rendi la tua lista di sola lettura e assicurati che sia inizializzata.
  • Utilizza un ObservableList nel tuo modello, in particolare se intendi associare o reagire alle modifiche.

Esempio (NOTA: presupporre che il tuo modello sia INotifyPropertyChanged e che invii notifiche su Id, Nome, ecc.

public class MyComplexModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ObservableList<MyComplexModelFeedback> Feedback { get; } = new ObservableList<MyComplexModelFeedback>();
}

Ciò consente al ViewModel di aggiornare e riepilogare i voti in base alle esigenze. Esempio (presuppone callback quando il modello è cambiato):

public class MyComplexModelViewModel : ViewModel<MyComplexModel>
{
    public float Votes { get; }

    protected void OnModelChanged(MyComplexModel oldModel, MyComplexModel newModel)
    {
        oldModel?.Feedback.CollectionChanged -= OnFeedbackChanged;
        newModel?.Feedback.CollectionChanged += OnFeedbackChanged;
    }

    private void OnFeedbackChanged(object source, NotifyCollectionChangedEventArgs args)
    {
       Votes = CalculateVotes(Model.Feedback);

       RaisePropertyChanged(nameof(Votes));
    }
}

Lo lascerò per implementare il metodo CalculateVotes . Questo è solo un modo per mostrare come attivare il ricalcolo dei voti ogni volta che si modifica Feedback .

I livelli non devono cambiare qui, basta approfittare degli eventi che accadono con INotifyPropertyChanged o INotifyCollectionChanged classes. Un metodo alternativo è quello di evitare del tutto gli eventi e ricalcolare periodicamente le cose secondo necessità. Entrambi possono funzionare a seconda di quanto sia complicato calcolare il tuo voto totale.

Il tuo View si occupa dell'associazione diretta sia a ViewModel sia a Model, a seconda di dove è necessario aggiornare il display. Puoi comunque mantenerlo semplice.

    
risposta data 07.06.2018 - 16:54
fonte

Leggi altre domande sui tag