MVVM: Um objeto VM deve expor um objeto M diretamente, ou apenas através de getters delegando para os getters de M?

StackOverflow https://stackoverflow.com/questions/1114555

Pergunta

A melhor maneira de explicar é com o exemplo, então:

este é o modelo

public class Person 
{
    public int age;
    public string name;
}

Este é o modelo de vista

public class PersonVM
{    
}

minha pergunta é:
A VM deve expor a pessoa ao modelo de dados ou encapsular as propriedades do modelo com suas próprias propriedades?

Foi útil?

Solução

O modelo de visualização deve declarar suas próprias propriedades e ocultar as especificidades do modelo da visualização. Isso oferece mais flexibilidade e ajuda a manter os problemas do tipo modelo de variação de vazar para as classes de modelos. Normalmente, as classes de modelo de visualização encapsulam o modelo por delegação. Por exemplo,

class PersonModel {
    public string Name { get; set; }
}

class PersonViewModel {
    private PersonModel Person { get; set;}
    public string Name { get { return this.Person.Name; } }
    public bool IsSelected { get; set; } // example of state exposed by view model

    public PersonViewModel(PersonModel person) {
        this.Person = person;
    }
}

Lembre -se: o modelo não deve saber nada sobre o modelo de visualização que o está consumindo, e o modelo de exibição não deve saber nada sobre a visualização que está consumindo. A visão não deve saber nada sobre os modelos à espreita em segundo plano. Assim, encapsula o modelo por trás das propriedades no modelo de exibição.

Outras dicas

Não há um acordo geral sobre essa questão. Por exemplo, foi uma das perguntas abertas sobre o MVVM formulado por Ward Bell aqui:

A VM pode oferecer ao V um objeto M não sacado (por exemplo, o funcionário da RAW)? Ou as propriedades do M-Object (se tiver permissão para ter propriedades!) Ser exposto exclusivamente através da superfície de um invólucro VM?

As principais vantagens de não expor diretamente o modelo na VM são:

  • Você pode usá -lo como um "conversor em esteróides", formando os valores do modelo de maneira conveniente para a visão

  • você pode injetar outra funcionalidade relacionada à interface do usuário, como mensagens de validação de dados, desfazer refazer,..

Os contras são:

  • Você terá que duplicar muito código para expor todas as propriedades dos modelos no ViewModel.

  • Se você vincular o controle de visualização à propriedade ViewModels, enviará os eventos do PropertyChanged do ViewModel. Mas o que acontece se a propriedade dos modelos mudar de outra fonte diferente do ViewModel Setter? Então ele deve notificar o ViewModel para que você termine com 2 onPropertyChanged, um no modelo e outro no viewmodel ... bastante complexo!

Então, para mim, a resposta correta é: depende de seus requisitos.

An interesting solution to this was proposed by Robert McCarter in MSDN volume 25.

http://msdn.microsoft.com/en-us/magazine/ff798279.aspx

He uses a dynamic View Model to provide a layer on top of the Model while avoiding proxying all of the Model properties.

If your problem space doesn't require high performance (dynamics do incur a performance hit), this is an excellent solution. The View does not need to know anything about the Model, but the View Model does not have to proxy properties that are being provided "as is." At any time properties can be added to the View Model to wrap the Model properties without modifying the View or the Model. Read the article for more details.

Having a ViewModel for any Model could be worse than that. What if you have a hierarchical structure of a Model, or even a simple collection? In that case you'll have to iterate through all models and build a ViewModel instance per-model, and also to register notify-change events or other events. IMHO, this is completely insane, and unreasonable. As DaniCE said, you’ll end up with lot of code and a big headache.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top