É uma boa ideia adicionar o ViewModel exatamente igual ao Model

16

Tenho as seguintes camadas na minha solução:

  1. App.Domain
  2. App.Service
  3. App.Core (talvez você chame este de App.DataLayer)
  4. App.Web

O padrão de design de software não é minha pergunta. Tenho o seguinte modelo Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Quero usar esse modelo na visualização (por exemplo, página inicial) E quero usar Id, Name & Value, portanto, se eu quiser criar o ViewModel, adicionarei o seguinte:

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Então, essa é uma boa ideia? ou apenas usar em Foovez de FooViewModel?

Mehdi Dehghani
fonte
Não sei se entendi isso. Não é o Modelgeralmente passado para o View? Por que exatamente você precisa recriar os campos do Modelno View? Se a separação de preocupações é uma meta MVC, em que circunstâncias alguém gostaria de fazer a mesma coisa com Modele View? Se ViewModelsão ambos, por que não estendendo / compondo ambos Modele View?
Nulo
por favor, leia meus comentários na resposta de @ svidgen
Mehdi Dehghani
Eu tenho um problema relacionado - onde a validação (atributo obrigatório) nos modelos (e no banco de dados) declara que certos valores devem ser inseridos - mas, nas visualizações, esses valores não precisam ser -, então sou forçado a copiar alguns campos de os modelos no modelo de visualização - em vez de fazer referência diretamente ao modelo. No entanto, pensando bem, isso provavelmente é bom e, de fato, não viola o DRY, pois é para diferentes propósitos (não muito mal de qualquer maneira).
Niico 21/09

Respostas:

20

Isso pode parecer uma violação da regra DRY inicialmente, mas eu argumentaria que "código semelhante e até idêntico" não é necessariamente "repetição" se fizer algo diferente ou puder mudar de forma independente. E no caso dos modelos de visualização, o código está definindo o que o "cliente" vê, não necessariamente as entidades e operações sobre as quais o negócio fala. Portanto, você costuma revelar modelos para o cliente ou interface que são "incidentalmente idênticos". Você pode alterar as regras e os termos comerciais ou a terminologia do usuário final independentemente um do outro.

Então, eu voltaria a pergunta para você. Se o domínio mudar, é aceitável que os clientes da "versão 1" continuem usando as interfaces antigas? Você nunca revelará termos ou operações na interface que não fazem parte das "principais regras de negócios?" E vice versa?

Esse tipo de pergunta em mente, se a "função" da sua exibição é estritamente para revelar o modelo de domínio subjacente, sim, isso parece violar a regra DRY.

Também tenha em mente, expor uma visão que muda mais naturalmente com as alterações do modelo também pode ser realizada em alguns idiomas com atributos e reflexão dos membros. (Ou com menos repetição em outros feitos de esperteza ... Mas, "esperteza" geralmente falha em justificar a repetição que ela poupa.)

svidgen
fonte
Boas notas mencionadas (vote a favor), como eu disse como comentário na resposta anterior, estou falando de uso geral, criação de imagens, talvez alguns dias depois, decidi adicionar um novo campo / propriedade Foo, portanto, se eu usasse Fooo ViewModel Além disso, o cliente também receberá novas propriedades. E se esse novo fosse um campo de segurança (talvez verdadeiro / falso para permissão ou algo parecido), o que devo fazer?
Mehdi Dehghani
@mehdi, você precisará ser mais específico sobre qual campo você está pensando em adicionar e por que você acha que ele pertence ou não à visualização. Ou, em geral, qual é a preocupação.
svidgen
@mehdi para ser claro, se você está preocupado com os usuários finais alterar um valor de segurança, o seu domínio simplesmente não deveria permitir que os usuários para salvar as coisas que eles não estão autorizados para salvar
svidgen
Por que estamos usando o ViewModels? existem alguns motivos, como sabemos, um deles é para segurança, por exemplo, User edit formnão precisamos passar IsAdmincampo para o cliente, para manter esse campo seguro, então é com isso que me preocupo. desculpe pelo meu inglês ruim.
Mehdi Dehghani
1
Em outras palavras, acho que a pergunta original é uma pergunta completa. A pergunta que você está tentando descobrir nos comentários aqui é outra questão completa. E os comentários não são uma boa maneira de obter respostas boas e de qualidade.
precisa saber é
2

Eu teria um modelo de exibição que continha apenas uma propriedade, uma instância do Foo. Dessa forma, você não está violando o DRY de acordo com qualquer definição, se o Foo mudar, seu modelo de visualização verá a alteração automaticamente e você ficará livre de uma ligação direta do modelo de visualização ao modelo.

Se amanhã for necessário que o view mostre algo mais, além do Foo, você pode simplesmente adicionar uma nova propriedade, e a intenção do seu modelo de view ainda será clara, ele contém um Foo e algo mais, você não terá uma mistura de propriedades da Foo com outras propriedades não relacionadas.

Eu não pensaria no seu modelo de visão como um FooViewModel, pensaria nele em termos do que a visão deveria exibir. Se ele exibir apenas um Foo, o modelo de visualização conterá uma propriedade, um Foo.

Não tenho certeza se expliquei isso claramente. Caso contrário, avise-me e tentarei reformulá-lo quando estiver acordado!

Avrohom Yisroel
fonte
-2

Eu diria que o uso FooViewModeldessa maneira viola o princípio DRY. Quando você precisa fazer uma alteração, Footambém precisa fazer uma alteração FooViewModel. Eu acho que você seria melhor servido simplesmente usando Foocomo modelo para a sua opinião. Eu consideraria um modelo de exibição se você precisar exibir coisas do Foo e outras coisas. Por exemplo, digamos que você precise renderizar algumas informações de Fooe também de Bar.

zero_dev
fonte
Por favor, diga-me, se eu decidisse adicionar outro campo / propriedade ao Foo, então, porque eu também usei Fooo ViewModel, também tenho que passar esse novo campo para o modo de exibição, acho que isso não é realmente um bom negócio, o que você acha ?
Mehdi Dehghani
Não vejo nada de errado em ter o modo de exibição usar apenas um subconjunto dos dados expostos pelo modelo. Eu acho que a falta maior é a união entre Fooe FooViewModel. Geralmente, não é uma boa ideia ter que modificar vários arquivos para uma única alteração lógica.
zero_dev 9/08/2015
E se esse campo adicionado fosse um campo de segurança, como algum true/falsevalor para permissão ou algo assim.
Mehdi Dehghani
Você não precisa expor esses campos na própria Visualização, mas deve garantir que o restante do seu código não permita que o usuário altere seu nível de segurança, caso um usuário mal-intencionado tente POSTAR essa alteração.
Graham
Parece que estaria aberto a ataques de atribuição de massa
James