Uma visão e um modelo devem se comunicar ou não?

33

De acordo com a página da Wikipedia para a arquitetura MVC , a visualização é livre para ser notificada pelo modelo e também é livre para consultar o modelo sobre seu estado atual. No entanto, de acordo com o curso de Paul Hegarty no iOS 5 na Stanford, aula 1, página 18, toda interação deve passar pelo controlador, com Model e View que nunca devem se conhecer. Não está claro para mim se a afirmação de Hegarty deve ser uma simplificação do curso, mas estou tentado a dizer que ele pretende o design como tal.

Como você explica esses dois pontos de vista opostos?

Stefano Borini
fonte

Respostas:

26

Este é um tópico controverso no MVC / MVVM. Alguns dizem que não há problema em o View acessar os modelos diretamente, outros dizem que você deve agrupar os modelos no ViewModels para abstraí-los da visualização. Pessoalmente, não sou fã de nenhuma dessas abordagens.

O principal objetivo do MVC / MVVM é dissociar a interface do usuário, a lógica de negócios e os dados. Portanto, com esse conceito em mente, permitir que o View acesse diretamente os modelos cria uma dependência que você pode não querer ter. Por outro lado, agrupar os modelos no ViewModels geralmente é tedioso e não é muito útil, pois os ViewModels tendem a agir simplesmente como uma passagem para os modelos.

Eu gosto da abordagem de ter seus modelos implementando uma interface específica, vamos chamá-la de IModel. Sua classe ViewModel pode oferecer instâncias de objetos que implementam o IModel para consumo da View. O View simplesmente sabe que funciona com objetos IModel obtidos do ViewModel. Isso remove o código externo do wrapper ViewModel e oculta a implementação concreta do IModel da View. Posteriormente, você pode trocar uma implementação do IModel por outra sem afetar o bit Visualizar.

Raymond Saltrelli
fonte
1
Em relação aos aspectos tediosos do mapeamento de um modelo para um modelo de visualização, deve-se notar que existem ferramentas disponíveis que podem aliviar a dor do mapeamento. Por exemplo: (.NET AutoMapper) (JAVA modelmapper)
Jesse
+1 Ótima resposta! Essa é uma ótima abordagem, dependendo da complexidade do seu modelo, mas a maioria dos modelos hoje são do tipo Anêmico . Elementos do modelo, sendo pouco mais que objetos de dados sem comportamento, vejo pouca ou nenhuma necessidade dessa abstração e pouco perigo em permitir que o seu View acesse diretamente o seu Modelo.
maple_shaft
2
Eu ouço o que você está dizendo; a maioria das interfaces IModel conteria simplesmente um monte de declarações de propriedades e poucas (se houver) declarações de método. Mas mesmo que os modelos sejam anêmicos, a interface ainda desacopla o View de sua implementação concreta. Essa separação pode não ser necessária para todos os projetos, mas é sempre uma boa idéia manter suas opções em aberto.
Raymond Saltrelli
1
Estou confuso, se você tem um monte de visualizações absolutamente diferentes, como pode confiar em uma interface sem bagunçar tudo? Eu acho que os modelos de exibição são fantásticos. Você cria modelos que são genéricos o suficiente para serem usados ​​em todo o aplicativo e cria modelos de exibição para consumir um ou mais modelos e implementar adicionalmente operações que somente seriam usadas por essa exibição.
O homem de muffin
12

Na web, todos chamam de desacoplamento MVC.

Algumas tecnologias, como C #, usam MVVM porque não há link entre o View e outro, tudo passa pelo localizador de serviço, vinculando as variáveis.

No MVC puro, o View conversa diretamente com o Modelo e vice-versa. O Controlador está lá apenas quando surgir alguma alteração.

E depois, existe o chamado PAC (Presentation Abstraction Control). Nessa arquitetura, o View e o Model não se comunicam. O Controller é o único autorizado a fazer qualquer coisa com a View ou o Model. As pessoas frequentemente confundem isso com o MVC.

Você verá uma explicação muito melhor aqui: http://www.garfieldtech.com/blog/mvc-vs-pac

Florian Margaine
fonte
7

Para mim, o objetivo básico de uma arquitetura é não impedir futuras tentativas de refatoração. Normalmente, as visualizações que interagem diretamente com os modelos atendem a esse requisito, e é relativamente claro quando não.

Quando uma visão está se tornando muito íntima com um modelo, um ViewModel pode ser uma coisa bonita, mas geralmente é o caso para mim que as instâncias em que ela é solicitada são minoria.

ameaçadoramente
fonte
6

No MVC , Paul Hegarty está errado. O controlador refere-se a eventos do usuário, não à comunicação de modelo para visualização. No CVM clássico , as vistas observam o modelo (padrão do observador).

Com o intermediário entre fazer a mediação, o padrão deve ser chamado de MVP e, de fato, a maior parte do que hoje é apresentado como MVC, fica mais próxima do MVP.

Depois, há o MVVM, que é algo semelhante aos dois, e ainda um pouco diferente, e existia há muito tempo ... é melhor vê-lo como dois MVCs / MVPs ligados entre si através do objeto viewmodel - o MVC "cliente" tem o viewmodel como seu modelo e o MVC "server" tem o viewmodel como sua view.

Herby
fonte
1
Hoje (início de 2014), para mim (com meu nó e pilha angular) essa distinção entre MVC "cliente" e MVC "servidor" parece muito relevante e de alguma forma esclarecedora. (obrigado)
slacktracer
4

Como você está perguntando sobre o material dessas palestras de Stanford em particular, vale a pena considerar duas coisas sobre a posição de Hegarty:

  1. Como você mencionou, ele está ministrando um curso de ciência da computação de nível 100. Há muitas vagas em suas palestras em que ele simplifica, encobre os detalhes ou diz "faça dessa maneira", como provavelmente é necessário ao ensinar o básico, ou seja, você precisa dominar as regras antes de poder quebrá-las.
  2. Minha experiência com o SDK do iOS é que, onde não impõe uma separação estrita entre o View e o Model, ele é voltado fortemente para esse padrão. Ao escrever aplicativos para iOS em particular, aderir à separação de exibição de modelo ajuda a escrever um código que esteja de acordo com as expectativas da estrutura. Eu hesitaria em generalizar as declarações de Hegarty para desenvolvimento em outras plataformas ou em geral.
Dan J
fonte
1

Eu concordo com Paul Hegarty e acredito que a View não deve conhecer o modelo. Não é tão difícil de alcançar, mas traz benefícios adicionais ao seu design e flexibilidade futura.

Em aplicativos pequenos (geralmente na área de trabalho) em que eu gostaria de evitar classes "fictícias" do ViewModel e manter as coisas simples, também uso a interface IModel (veja a resposta acima) e cuido para que o Model não tenha idéia do View (use assinantes) como no MVC clássico).

Também neste caso, o Controlador está bastante acoplado ao View e, por simplicidade, nem sempre os separo claramente.

A segunda abordagem "simplificada" é boa quando você pode ter várias visualizações para o mesmo modelo, mas eu não recomendaria se você gostaria de usar a mesma visualização para modelos diferentes. Sob diferente, quero dizer realmente diferente por natureza, e não apenas as classes de teste JUnit que “seguem” o modelo principal.

Dime
fonte
1

Eu acredito que não existe uma regra rígida para isso, depende totalmente de suas necessidades.

Você encontrará pessoas com crenças diferentes. Arquiteturas são conceitos para ajudar a projetar melhores soluções.

Além da comunicação de visualização de modelo, há mais uma contradição sobre a lógica de negócios no MVC. Muitas pessoas acreditam que toda a lógica de negócios deve ser um modelo (veja essa pergunta do SO ), por outro lado, o link compartilhado por Florian (em sua resposta) diz que a lógica de negócios deve estar no controlador.

Além disso, existe a possibilidade de dividir a lógica de negócios em lógica de aplicativo (coloque no controlador) e logon no domínio (coloque no modelo).

Portanto, a moral da história é MVC significa que modelo, visão e controlador devem ser separados. Fora isso, o que melhor lhe convier.

Mohit Leekha
fonte
0

Eu uso o DTO para comunicação de visualização de modelo.

Por exemplo:

  • O usuário preenche o formulário de atualização (exibir)
  • Usuário envia formulário
  • O controlador vincula os dados do formulário ao UserUpdateDTO
    • O DTO e o UserModel são POJOs, mas o DTO não possui ID e nome de usuário porque não podemos atualizar o nome de usuário.
    • Outra diferença é que a classe Model possui relações e associações, mas o DTO armazena apenas dados e podemos adicionar validadores JSR 303 a ele
  • Controladores diz para fazer a manutenção da camada para economizar
  • Camada de serviço diz para a camada DAO para persistir os dados
Fırat KÜÇÜK
fonte
-1

Estou no campo que diz que a visão nunca deve se comunicar com o modelo. O controlador sempre deve ser o principal responsável por tudo, depois decide o que fazer (validar, solicitar dados do modelo etc.).

Costumo vê-lo mais como uma questão organizacional do que qualquer outra coisa.

elvispt
fonte
-1

Como muitos são sugeridos sobre por que e como a visualização e o modelo devem interagir livremente em diferentes contextos, o principal motivo do iOS para criar o Controller é o mediador entre eles é evitar as dependências do Model & View em sua base de código e nos permitir reutilizar modelo ou visualização de acordo com os requisitos com a evolução do iOS.

Como talvez seja necessário manter as atualizações de nossos aplicativos na interface do usuário / UX ou modelo ou algumas vezes, ele não deve produzir código de dependência de modo entre o modelo e a visualização. alterá-lo, você ainda poderá reutilizar o mesmo modelo e vice-versa.

Embora eu concorde que o MVC no iOS produz ViewControllers gigantes com muitas lógicas diferentes e lida com todo tipo de coisa que não seja a que se destina, é melhor usar o MVVM ou os Controles de apresentação para tornar sua base de código mais flexível e fácil para leitura e manutenção com ViewControllers menores.

Isso pode ajudar quem procura ViewControllers menores no iOS:

http://blog.xebia.com/simplification-of-ios-view-controllers-mvvm-or-presentation-controls/

Ajay Babu
fonte