Devemos vincular a visualização a uma propriedade de modelo ou o ViewModel deve ter sua própria ...?

21

Estou iniciando um projeto com o seguinte ambiente técnico: .Net 4.0, Entity Framework 4.0, WPF com arquitetura MVVM

Vi muitos exemplos na rede, alguns livros com esse ambiente. Em alguns dos exemplos, os autores tiveram essa ideia:

  1. O Viemodel terá uma instância da classe Model (Entity Framework Entity, por exemplo, Person)
  2. Vincule os controles de exibição do WPF às propriedades do Model

Enquanto alguns autores fizeram:

  1. O Viemodel irá expor todas as propriedades do modelo.
  2. Vincule os controles de exibição do WPF às propriedades do ViewModel e não diretamente ao modelo.

Portanto, é uma boa ideia deixar a visualização vincular propriedades do modelo ao invés de exibir o próprio modelo? Ou qual é o mais preferido?

Pravin Patil
fonte
Pessoalmente, acho que a exposição das propriedades do modelo resulta em uma boa separação da camada de dados e da lógica.
Alex Hope O'Connor

Respostas:

25

Eu acho que muitos programadores tentam primeiro pegar o atalho de ligação diretamente ao modelo, mas na minha experiência isso tem algumas desvantagens. O principal problema é que, se o modelo da sua entidade for persistido pelo NHibernate ou similar, assim que a Visualização atualizar a propriedade do modelo, o NHibernate poderá persistir com essas alterações no banco de dados. Isso não funciona bem para telas de edição que possuem um botão Salvar / Cancelar. Na verdade, ele pode optar por esperar e persistir tudo como um lote, mas a idéia é que, quando você altera o modelo, está comprometendo sua alteração.

Portanto, você ainda pode se safar da ligação diretamente às propriedades do modelo em telas somente leitura, mas terá uma inconsistência.

Além disso, a maioria dos modelos não é implementada, INotifyPropertyChangedportanto, eles podem não ser destinos de ligação adequados se o estado da tela mudar após a exibição inicial.

Dada a facilidade das propriedades automáticas, sugiro sempre vincular a View ao ViewModel, não ao Model. É consistente, simples e oferece a maior flexibilidade para suportar mudanças no futuro.

Scott Whitlock
fonte
Eu gosto da sua resposta. +1 por mencionar Editar / Salvar Tela. Mas seria assustador escrever as propriedades duas vezes - uma vez no modelo e novamente no modelo de exibição. Também aumentaria o tempo de desenvolvimento. Você acha que é justificável fazê-lo ...?
Pravin Patil
9
@ Patin Patil - fwiw, toda vez que tomo esse atalho, me xinguei mais tarde, quando tive que voltar e consertá-lo. Há relativamente pouco esforço para reimplementar as propriedades no ViewModel, especialmente se forem somente leitura (porque você pode usar propriedades autoimplementadas com um setter privado). O fato é que, na maioria dos casos, o Model é uma estrutura de dados diferente da do ViewModel. Deixe a flexibilidade de alterar o modelo sem afetar a visualização. Quanto menos você precisar alterar a Visualização, melhor, porque é difícil testá-la.
Scott Whitlock
4
@ Scott Whitlock: Estou desenvolvendo aplicativos WPF com o NHibernate há dois anos e nunca tive nenhum problema vinculativo diretamente ao modelo. De fato, quando uma propriedade de modelo é alterada, é basicamente o mesmo esforço para a alteração, independentemente do que você vinculou. E quando realmente preciso fazer algum roteamento no próprio ViewModel mais tarde, não vale a pena investir o tempo antes de precisar. Sigo a abordagem YAGNI (ainda) e não tenho dificuldades. Eu acho que você e os outros aqui estão sendo um pouco dogmáticos sobre esse assunto.
Falcon
16

O ponto de a ViewModelé que é um modelo do View.

Você deve ser obrigatório o ViewModelàs View, e não quaisquer Modelpropriedades (não diretamente, de qualquer maneira).

Oded
fonte
8

Acho os dois métodos aceitáveis

A ligação apenas ao ViewModel é a abordagem "MVVM-purist" e leva a uma melhor separação entre as camadas. A ligação ao modelo geralmente é mais rápida e conveniente.

A menos que eu tenha um bom motivo para separar completamente as camadas (tamanho do projeto, preocupações futuras de manutenção, tipo de modelo com o qual estou trabalhando etc.), vinculo-me ao modelo.

Rachel
fonte
7

Eu acho que o que você está vendo é um conceito chamado bind through, ou seja, se o seu modelo tem uma propriedade chamada name e seu view-model expõe essa propriedade sem nenhuma edição ou conversão adicional, é possível vincular o modelo ao que seria.

Pseudo-código:

 {Binding: MyViewModel.MyModel.Name}

Isso é feito para reduzir a quantidade de propriedades 'Fluff' no modelo de visualização, infelizmente, também é uma má ideia a longo prazo. O conceito de um modelo de visualização é garantir que a visualização não dependa de uma dependência do modelo. Ao vincular você agora deve garantir que seu modelo contenha uma propriedade chamada name, caso contrário sua implementação será interrompida.

Se você ligar apenas até o modelo de vista, no entanto, poderá alterar o modelo e a visualização nunca saberá, pois apenas verá a propriedade denominada Nome no modelo de visualização.

Agora, isso pode ser atenuado em determinadas circunstâncias, caso seu modelo seja baseado em uma interface. Portanto, se a interface tiver um IBaseDetails que expõe a propriedade ModuleName, você poderá:

Pseudo-código:

 {Binding: MyViewModel.MyModel.ModuleName}

Contanto que qualquer um dos modelos que você faça atenda à interface do IBaseDetails, você estará ciente, no entanto, de que este é um caso extremo e, em geral, você é 90% sempre melhor para envolver seu modelo de exibição em todos os modelos que ele cobre.

DeanMc
fonte
2

Se você estiver vendo muito atrito tentando ir de Model -> ViewModel, tente algo como o AutoMapper. Remove o tédio associado às propriedades de cópia manualmente.

Bryan Boettcher
fonte
1

Eu cheguei aqui só porque tinha a mesma dúvida e me convenci de que sempre ligaria para visualizar o modelo em vez de para o modelo.

Adote a abordagem da forma reativa angular. Você cria um grupo de formulários usando algumas informações no modelo de exibição, mas depois precisa acessar o formulário. Valores para obter os valores e copiar valores no modelo usando qualquer mapeador automático ou manual. Acho que não há coisa mais bonita do que se limitar a propriedades no modelo de visualização, digamos, por exemplo, que eu tenho uma página de visualização do projeto em que tenho o nome do projeto, nome do cliente etc.

Existe um relacionamento entre projeto e cliente, já que um projeto tem um cliente. Portanto, nesse nível, eu não deveria me importar com esse relacionamento. Eu só preciso mostrar visualmente o nome do projeto e o nome do cliente na visualização. Por isso, coloquei duas propriedades no nome do projeto e no nome do cliente do modelo de visualização, para vincular os controles de visualização a ambos. Para eles, mais tarde vou me preocupar em fornecer valores para essas propriedades no código por trás, retirando-o de qualquer estrutura que o modelo tenha.

O mesmo poderia ser feito para atualizar o modelo no caso de salvar / cancelar, não há nada mais limpo.

Ivan Carmenates García
fonte
é difícil ler este post (parede de texto). Você se importaria de editá -lo em uma forma melhor?
Gnat
Lá vai você, Saúde.
Ivan Carmenates García