Qual é a diferença entre MVC e MVVM? [fechadas]

1312

Existe uma diferença entre o padrão padrão "Model View Controller" e o padrão Model / View / ViewModel da Microsoft?

Bjorn Reppen
fonte
54
Observe que, embora o MVVM tenha sido cunhado pela Microsoft, muitos desenvolvedores e projetos que não são da Microsoft começaram a adotar esse padrão. Este comentário foi enviado a você pelo departamento de despeito dos MS-haters.
BoltClock
1
Tendo trabalhado com o MVVM por um longo tempo, meu primeiro contato com o MVC foi frustrante, até que eu aprendi que podia passar os ViewModels para o navegador usando técnicas de ligação encontradas no MVVM. Mas, como Joel disse acima, a única maneira de recuperar o estado do navegador é postando as alterações em um formulário (que usa nome / valor). Se você não entende bem esse ponto. Você terá dificuldades no MVC. Basta olhar para o controlador como um injetor de dependência para a visualização e está tudo pronto.
John Peters
2
Uma pergunta tão votada em alto nível [padrões de design]. Gostaria de sugerir o uso de diagramas nas respostas.
Ricardo
4
Aqui está uma versão arquivada do artigo de Joel: web.archive.org/web/20150219153055/http://joel.inpointform.net/…
Tereza Tomcova
1
Ao contrário do método MVC, o ViewModel não é um controlador. Em vez disso, atua como um fichário que vincula dados entre a visualização e o modelo. Enquanto o formato MVC é projetado especificamente para criar uma separação de preocupações entre o modelo e a visualização, o formato MVVM com ligação de dados é projetado especificamente para permitir que a visualização e o modelo se comuniquem diretamente entre si. hackernoon.com/...
blueray

Respostas:

684

MVC / MVVM não é um ou / ou escolha.

Os dois padrões surgem, de maneiras diferentes, no desenvolvimento do ASP.Net e Silverlight / WPF.

Para o ASP.Net, o MVVM é usado para vincular dados bidirecionais nas visualizações. Geralmente, é uma implementação do lado do cliente (por exemplo, usando o Knockout.js). O MVC, por outro lado, é uma maneira de separar as preocupações do lado do servidor .

Para Silverlight e WPF, o padrão MVVM é mais abrangente e pode parecer atuar como um substituto para o MVC (ou outros padrões de organização de software em responsabilidades separadas). Um pressuposto, que freqüentemente saiu desse padrão, foi que a ViewModelsimplesmente substituído o controlador MVC(como se você poderia apenas substituir VMpara Cna sigla e tudo seria perdoado) ...

O ViewModel não substitui necessariamente a necessidade de controladores separados.

O problema é que, para ser testado de forma independente *, e especialmente reutilizável quando necessário, um modelo de exibição não tem idéia de qual exibição está sendo exibida, mas o mais importante é que não tem ideia de onde seus dados são provenientes .

* Nota: na prática, os controladores removem a maior parte da lógica, do ViewModel, que requer teste de unidade. A VM então se torna um contêiner burro que requer pouco ou nenhum teste. Isso é bom, pois a VM é apenas uma ponte entre o designer e o codificador, portanto, deve ser simples.

Mesmo no MVVM, os controladores normalmente contêm toda a lógica de processamento e decidem quais dados serão exibidos em quais visualizações usando quais modelos de visualização.

Pelo que vimos até agora, o principal benefício do padrão ViewModel é remover o código do XAML code-behind para tornar a edição do XAML uma tarefa mais independente . Ainda criamos controladores, como e quando necessário, para controlar (sem trocadilhos) a lógica geral de nossos aplicativos.

As diretrizes básicas do MVCVM que seguimos são:

  • As visualizações exibem uma certa forma de dados . Eles não têm idéia de onde os dados vêm.
  • Os ViewModels mantêm uma certa forma de dados e comandos , eles não sabem de onde os dados ou código vêm ou como são exibidos.
  • Os modelos mantêm os dados reais (vários contextos, armazenamento ou outros métodos)
  • Os controladores ouvem e publicam eventos. Os controladores fornecem a lógica que controla quais dados são vistos e onde. Os controladores fornecem o código de comando ao ViewModel para que o ViewModel seja realmente reutilizável.

Também observamos que a estrutura de geração de código do Sculpture implementa o MVVM e um padrão semelhante ao Prism AND também faz uso extensivo de controladores para separar toda a lógica de casos de uso.

Não assuma que os controladores sejam obsoletos pelos modelos de exibição.

Eu iniciei um blog sobre este tópico, que adicionarei quando e como puder . Há problemas com a combinação do MVCVM com os sistemas de navegação comuns, pois a maioria dos sistemas de navegação usa Views e VMs, mas abordarei isso nos artigos posteriores.

Um benefício adicional do uso de um modelo MVCVM é que apenas os objetos do controlador precisam existir na memória durante a vida útil do aplicativo e os controladores contêm principalmente código e poucos dados de estado (por exemplo, pouca sobrecarga de memória). Isso resulta em aplicativos com muito menos memória do que soluções em que os modelos de exibição precisam ser mantidos e é ideal para certos tipos de desenvolvimento móvel (por exemplo, Windows Mobile usando Silverlight / Prism / MEF). Obviamente, isso depende do tipo de aplicativo, pois talvez você ainda precise reter as VMs em cache ocasionais para capacidade de resposta.

Nota: Este post foi editado várias vezes e não foi especificamente direcionado à pergunta restrita, portanto atualizei a primeira parte para agora também abordá-la. Grande parte da discussão, nos comentários abaixo, refere-se apenas ao ASP.Net e não à imagem mais ampla. Esta publicação pretendia cobrir o uso mais amplo do MVVM no Silverlight, WPF e ASP.Net e tentar desencorajar as pessoas de substituir os controladores pelo ViewModels.

Gone Coding
fonte
8
@ Tomasz Zielinski: É verdade, mas "onde eles são usados" não era a pergunta (ou o ponto da minha resposta). O que quero dizer é que os controladores ainda são úteis no MVVM.
Codificação passada
58
Concordo. Meu comentário foi causado por uma iluminação repentina e não porque eu discordei de você.
Tomasz Zieliński
Também usamos controladores para controlar o "fluxo" de visualizações em uma interface do usuário semelhante a um assistente.
riezebosch
3
@ Justin: Vejo que minha redação dessa frase é um pouco ambígua. Na verdade, quero dizer que o teste de unidade para todos os componentes é mais facilmente suportado, não apenas melhorando o teste do ViewModels (que, como você ressalta, não faz muito isso no MVCVM ... e é isso que você deseja). O benefício real dos controladores é que você está realmente removendo a maioria dos requisitos para teste do ViewModel (onde as pessoas mantêm a lógica do controlador) e colocando-o onde pode ser testado (principalmente controladores e modelos). O comentário de reutilização é específico para as VMs nessa frase. Eu editei.
Codificação ido
7
@TomaszZielinski M (MVVM) C
Mohamed Emad
273

Acho que a maneira mais fácil de entender o que esses acrônimos devem significar é esquecê-los por um momento. Em vez disso, pense no software com o qual eles se originaram, cada um deles. Realmente se resume à diferença entre a Web inicial e a área de trabalho.

À medida que cresciam em complexidade em meados da década de 2000, o padrão de design do software MVC - que foi descrito pela primeira vez na década de 1970 - começou a ser aplicado a aplicativos da web. Pense no banco de dados, nas páginas HTML e no código entre eles. Vamos refinar isso um pouco para chegar ao MVC: Para »banco de dados«, vamos assumir o banco de dados mais o código da interface. Para »páginas HTML«, vamos assumir modelos HTML mais código de processamento de modelos. Para »code inbetween«, vamos assumir que o usuário do mapeamento de código clica em ações, possivelmente afetando o banco de dados, causando definitivamente a exibição de outra visualização. É isso, pelo menos para o propósito desta comparação.

Vamos manter um recurso desse material da Web, não como é hoje, mas como existia há dez anos, quando o JavaScript era um aborrecimento humilde e desprezível, que os programadores reais fizeram bem em evitar: A página HTML é essencialmente burra e passiva . O navegador é um thin client ou, se preferir, um pobre cliente. Não há inteligência no navegador. Regra de recargas de página inteira. A »visualização« é gerada novamente toda vez.

Lembremo-nos de que esse caminho da Web, apesar de toda a raiva, era terrivelmente atrasado em comparação com a área de trabalho. Aplicativos de desktop são clientes gordos ou ricos, se você preferir. (Mesmo um programa como o Microsoft Word pode ser considerado algum tipo de cliente, um cliente para documentos.) São clientes cheios de inteligência, cheios de conhecimento sobre seus dados. Eles são stateful. Eles armazenam em cache os dados que estão manipulando na memória. Nenhuma porcaria como uma recarga de página inteira.

E essa maneira rica de área de trabalho é provavelmente a origem do segundo acrônimo, MVVM. Não se deixe enganar pelas letras, pela omissão dos C. Controladores ainda estão lá. Eles precisam ser. Nada é removido. Apenas adicionamos uma coisa: estado, dados armazenados em cache no cliente (e junto com ele inteligência para lidar com esses dados). Esses dados, essencialmente um cache no cliente, agora são chamados de »ViewModel«. É o que permite uma rica interatividade. E é isso.

  • MVC = modelo, controlador, visão = comunicação essencialmente unidirecional = baixa interatividade
  • MVVM = modelo, controlador, cache, visualização = comunicação bidirecional = interatividade avançada

Podemos ver que, com o Flash, o Silverlight e, o mais importante, o JavaScript, a Web adotou o MVVM. Os navegadores não podem mais ser legitimamente chamados de thin clients. Veja a programação deles. Veja o consumo de memória deles. Veja toda a interatividade Javascript nas páginas da web modernas.

Pessoalmente, acho mais fácil entender esse negócio de teoria e sigla olhando para o que ele se refere na realidade concreta. Conceitos abstratos são úteis, especialmente quando demonstrados em matéria concreta, de modo que o entendimento pode dar um ciclo completo.

 

Lumi
fonte
47
O MVC não se originou na web. Trygve Reenskaug introduziu o MVC no Smalltalk-76 na década de 1970.
Arialdo Martini
11
Mesmo que tenha sido alterado para "O MVC foi popularizado através do design de aplicativos da web". Eu argumentaria que isso é especulação sem a citação adequada.
Dan Bechard
4
Arialdo: Obrigado, eu não conhecia o Smalltalk-76. (Brincou com outros brinquedos naquela época. :) Brincadeiras à parte, é interessante a idade de alguns desses conceitos. - @ Dan, o que escrevi é: "[MVC] pode ter existido antes da [Web], mas a Web é como se popularizou entre as massas de desenvolvedores da Web." Eu ainda acho que está correto. Não tenho uma citação para isso, mas acho que não preciso de uma, porque a popularização em massa do MVC faz parte da minha experiência pessoal quando comecei como desenvolvedor da Web no início da última década. O Apache Struts estava em voga na época, com muitos beans para o MVC.
Lumi
5
O MVC não é "essencialmente uma comunicação unidirecional", pois os navegadores emitem Obtenção e publicação o tempo todo. Obtém e Publica podem alterar os valores dos campos encontrados na string de consulta. Isso oferece aos navegadores ampla oportunidade de enviar informações de volta ao controlador. O MVC foi desenvolvido com base no HTTP 1.0, que sempre teve em mente a comunicação bidirecional.
John Peters
13
Obrigado Lumi. Isso fez muito mais sentido para mim do que as outras respostas. Está correto? Eu não faço ideia. Mas, da minha perspectiva, era pelo menos coerente.
gcdev
175

O MVVM Model-View ViewModel é semelhante ao MVC, Model-View Controller

O controlador é substituído por um ViewModel . O ViewModel fica abaixo da camada da interface do usuário. O ViewModel expõe os dados e objetos de comando que a exibição precisa. Você pode pensar nisso como um objeto de contêiner que a visualização fornece para obter seus dados e ações. O ViewModel extrai seus dados do modelo.

Russel East faz um blog discutindo mais detalhadamente Por que o MVVM é diferente do MVC

TStamper
fonte
81
A frase "O controlador é substituído por um modelo de exibição" não está correta. No MVVM, qual o papel do controlador é a ligação de dados (ou a ligação por convenção, se você a usar).
DaniCE 23/03
9
O MVVM só fará sentido ao usar a ligação de dados bidirecional do WPF. Caso contrário, o MVC / MVP etc seria suficiente.
Jeff
266
@DaniCE: Josh Smith:If you put ten software architects into a room and have them discuss what the Model-View-Controller pattern is, you will end up with twelve different opinions. …
sll
7
@OmShankar O 11º não é de si mesmo. Há 10 pessoas no total e 12 opiniões no total. O ditado quer dizer que as definições desses padrões são tão abertas à interpretação que pelo menos duas pessoas ficam confusas o suficiente para ter mais de uma opinião.
Dan Bechard #
7
@DaniCE Bem, esse é realmente o ponto da ligação de dados do WPF, e a Microsoft inventou o MVVM, pois é possível ignorar completamente o controlador (alegando que a frase "O controlador está sendo substituído por um modelo de exibição" está incorreta apenas porque há um controlador nos bastidores, é basicamente como reivindicar uma declaração "Linguagem de nível superior substitui o uso de código de máquina enigmático por códigos mais legíveis" para estar incorreta porque a linguagem de máquina nos bastidores ainda está sendo usada ...)
yoel halb
91

Por um lado, MVVM é uma progressão do padrão MVC que usa XAML para manipular a exibição. Este artigo descreve algumas das facetas dos dois.

O principal impulso da arquitetura Model / View / ViewModel parece ser que, no topo dos dados ("o Model"), existe outra camada de componentes não visuais ("the ViewModel") que mapeia os conceitos dos dados mais de perto aos conceitos da visualização dos dados ("a Visualização"). É o ViewModel ao qual o View se liga, não o Model diretamente.

Chris Ballance
fonte
20
Eu acho que o parágrafo que você citou resume muito bem o IMHO. Um aspecto do ViewModel é que é uma versão achatada / alterada do modelo para a visualização. Muitos outros padrões de MV * se vinculam ao modelo real .
217 Daniel Auger
1
? "Muitas outras MV * padrões ligam novamente o modelo real” Realmente eu pensei que a visão foi sempre suposto ligam ao controlador no MVC, não importa o quê.
PlagueHammer
9
Noturno: No MVC clássico, o View não tem muito a ver com o controlador, ele se liga principalmente ao Model. Pense nisso como um robô - o modelo representa a posição das articulações do robô, o View é um monitor LCD no qual você vê o robô, o controlador é, por exemplo, o teclado. Nessa configuração, o View depende do modelo, ou seja, a posição espacial do robô, que você pode ver no monitor é uma representação direta do modelo.
Tomasz Zieliński
@Nocturne O que daniel parecia dizer é que, embora oficialmente todos os MV * devam usar uma VM separada, muitos desenvolvedores simplesmente a ignoram e passam o modelo real, e de fato nada nas especificações, por exemplo, do MVC o desaprova, mas no MVVM deve uma VM sendo responsável fot a transição entre o modelo ea vista
halb yoel
Eu diria assim: O modelo é uma coisa do armário para o esquema do banco de dados. Quando uma consulta é executada, ela pode projetar os dados em tipos fortes na camada do modelo. O viewmodel é uma coleção de itens, incluindo objetos de modelo, mas pode e mantém o estado da visualização com relação aos dados. O controlador é simplesmente um policial de trânsito entre o viewmodel e a view e, claro, a view se preocupa apenas com os estados da view.
John Peters
52

A Microsoft forneceu uma explicação do padrão MVVM no ambiente Windows aqui .

Aqui está uma seção crucial:

No padrão de design Model-View-ViewModel, um aplicativo é composto por três componentes gerais. insira a descrição da imagem aqui

  • Modelo : representa o modelo de dados que seu aplicativo consome. Por exemplo, em um aplicativo de compartilhamento de imagens, essa camada pode representar o conjunto de imagens disponíveis em um dispositivo e a API usada para ler e gravar na biblioteca de imagens.

  • Exibição : um aplicativo normalmente é composto de várias páginas da interface do usuário. Cada página mostrada ao usuário é uma visualização na terminologia MVVM. A visualização é o código XAML usado para definir e estilizar o que o usuário vê. Os dados do modelo são exibidos para o usuário e é tarefa do ViewModel alimentar esses dados com a interface do usuário com base no estado atual do aplicativo. Por exemplo, em um aplicativo de compartilhamento de imagens, as visualizações seriam a interface do usuário que mostraria ao usuário a lista de álbuns no dispositivo, as fotos de um álbum e talvez outra que mostrasse ao usuário uma foto específica.

  • ViewModel : o ViewModel vincula o modelo de dados, ou simplesmente o modelo, à interface do usuário, ou visualizações, do aplicativo. Ele contém a lógica com a qual gerenciar os dados do modelo e expõe os dados como um conjunto de propriedades às quais a interface do usuário ou visualizações do XAML podem se vincular. Por exemplo, em um aplicativo de compartilhamento de imagens, o ViewModel expõe uma lista de álbuns e, para cada álbum, expõe uma lista de fotos. A interface do usuário é independente de onde as imagens vêm e como são recuperadas. Ele simplesmente conhece um conjunto de imagens expostas pelo ViewModel e as mostra ao usuário.

Esteira
fonte
7
Observe que, embora o artigo mencionado se aplique ao desenvolvimento com o Microsoft Stack - especificamente o Windows Phone - e o XAML, ele não precisa ser assim.
Richard Nalezynski
Esta resposta destaca o problema com o nome "MVVM" - deve ser "VVMM" ou "MVMV" - o MV-VM tem os relacionamentos completamente da maneira errada!
27419
45

Eu pensei que uma das principais diferenças era que no MVC, seu V lê seu M diretamente e passa pelo C para manipular os dados, enquanto no MVVM, sua VM atua como um proxy M, além de fornecer a funcionalidade disponível para você V.

Se não estou cheio de lixo, fico surpreso que ninguém tenha criado um híbrido, onde sua VM é apenas um proxy M e C fornece todas as funcionalidades.

George R
fonte
1
+1. O termo é o correto, eu acho. mas criar um híbrido M-MProxy-VC não é muita separação? Eu acho que seria o suficiente usando MVC enquanto M é um modelo com suporte completo de ligação. ;)
ktutnik
2
+1. Como comentei acima, acho que o MVC é usado para arquitetar todo o aplicativo (web), enquanto o MVVM é usado no componente View do MVC.
Tomasz Zieliński
23
@ktutnik: O modelo geralmente fica no servidor, enquanto o ViewModel fica no cliente. Portanto, não é possível vincular diretamente o HTML ao modelo do servidor. Portanto, precisamos do ModelView, que atua como um conjunto de dados local, não salvo, extraído do modelo usando, por exemplo, AJAX / JSON.
Tomasz Zieliński
1
A visualização realmente "lê" os dados do modelo porque eles já foram colocados lá pelo controlador. Eu gosto de me referir a ele como uma "injeção de dados" pelo controlador, pois é realmente o controlador que está no comando. Toda a visão faz em renderizar e disparar eventos em minha mente.
John Peters
3
Peço desculpas, mas discordo da interpretação do MVVM. Um ViewModel não tem idéia sobre um View ou como será um View ou como ele responderá, e um Model da mesma forma não tem idéia de um ViewModel. De fato, um View também não deveria conhecer um Modelo, apenas um ViewModel. O modelo deve representar os dados e o estado do aplicativo, o ViewModel deve converter o estado em dados compatíveis com a interface do usuário (recomendo todas as primitivas neste momento) e um View deve reagir à tradução do ViewModels. Os dados geralmente são os mesmos, mas ainda devem ser agrupados e entregues novamente por meio de um ViewModel e não existem controladores.
Michael Puckett II
24

MVC é um ambiente controlado e MVVM é um ambiente reativo.

Em um ambiente controlado, você deve ter menos código e uma fonte comum de lógica; que sempre deve estar dentro do controlador. Contudo; no mundo da web, o MVC é facilmente dividido em lógica de criação de exibição e lógica dinâmica. A criação vive no servidor e vidas dinâmicas no cliente. Você vê isso muito com o ASP.NET MVC combinado com o AngularJS, enquanto o servidor criará um View e passará em um Model e o enviará ao cliente. O cliente irá interagir com a View, caso em que o AngularJS entra como um controlador local. Depois de enviado, o Modelo ou um novo Modelo é passado de volta ao controlador do servidor e tratado. (Assim, o ciclo continua e existem muitas outras traduções desse manuseio ao trabalhar com soquetes ou AJAX etc., mas em toda a arquitetura é idêntica.)

MVVM é um ambiente reativo, o que significa que você normalmente escreve um código (como gatilhos) que será ativado com base em algum evento. No XAML, onde o MVVM prospera, tudo isso é feito facilmente com a estrutura de ligação de dados integrada, MAS, como mencionado, funcionará em qualquer sistema em qualquer View com qualquer linguagem de programação. Não é específico do MS. O ViewModel é acionado (geralmente um evento alterado de propriedade) e o View reage a ele com base nos gatilhos que você cria. Isso pode ser técnico, mas a linha inferior é que a Visualização é sem estado e sem lógica. Simplesmente muda de estado com base em valores. Além disso, os ViewModels são sem estado com muito pouca lógica e os Modelos são o Estado com lógica essencialmente Zero, pois devem apenas manter o estado. Eu descrevo isso como estado do aplicativo (Modelo), tradutor de estado (ViewModel) e, em seguida, o estado visual / interação (View).

Em um desktop MVC ou aplicativo do lado do cliente, você deve ter um Modelo, e o Modelo deve ser usado pelo Controlador. Com base no modelo, o controlador modificará a visualização. As vistas são geralmente vinculadas aos controladores com interfaces, para que o controlador possa trabalhar com uma variedade de vistas. No ASP.NET, a lógica do MVC é um pouco atrasada no servidor, pois o Controller gerencia os modelos e os transmite a uma exibição selecionada. O View é preenchido com dados com base no modelo e possui lógica própria (geralmente outro conjunto MVC, como o feito com o AngularJS). As pessoas argumentam e confundem isso com o aplicativo MVC e tentam fazer as duas coisas, mantendo o projeto eventualmente se tornando um desastre. SEMPRE coloque a lógica e o controle em um local ao usar o MVC. NÃO escreva a lógica do View no código por trás do View (ou no View via JS for web) para acomodar os dados do Controller ou Model. Deixe o controlador alterar a exibição. A única lógica que deve estar em uma View é o que for necessário para criar e executar através da interface que está sendo usada. Um exemplo disso é enviar um nome de usuário e senha. Seja na área de trabalho ou em uma página da Web (no cliente), o Controller deve lidar com o processo de envio sempre que a View dispara a ação Enviar. Se feito corretamente, você sempre poderá encontrar facilmente um aplicativo da Web ou local do MVC. Seja na área de trabalho ou em uma página da Web (no cliente), o Controller deve lidar com o processo de envio sempre que a View dispara a ação Enviar. Se feito corretamente, você sempre poderá encontrar facilmente um aplicativo da Web ou local do MVC. Seja na área de trabalho ou em uma página da Web (no cliente), o Controller deve lidar com o processo de envio sempre que a View dispara a ação Enviar. Se feito corretamente, você sempre poderá encontrar facilmente um aplicativo da Web ou local do MVC.

MVVM é pessoalmente o meu favorito, pois é completamente reativo. Se um modelo muda de estado, o ViewModel escuta e traduz esse estado e é isso !!! O View está ouvindo o ViewModel para alteração de estado e também é atualizado com base na tradução do ViewModel. Algumas pessoas chamam isso de MVVM puro, mas realmente existe apenas um e eu não me importo com o que você argumenta, e é sempre o MVVM Pure, onde o View não contém absolutamente nenhuma lógica.

Aqui está um pequeno exemplo: digamos que você deseja que um menu deslize pressionando um botão. No MVC, você terá uma ação MenuPressed em sua interface. O Controlador saberá quando você clicar no botão Menu e, em seguida, informará a Visualização para deslizar no Menu com base em outro método de Interface, como SlideMenuIn. Uma viagem de ida e volta por que motivo? No caso de o controlador decidir que você não pode ou deseja fazer outra coisa, é por isso. O Controlador deve estar encarregado da Visão, com a Visão não fazendo nada, a menos que o Controlador o diga. CONTUDO; no MVVM, o menu slide na animação deve ser incorporado e genérico e, em vez de ser instruído a inseri-lo, o fará com base em algum valor. Por isso, ouve o ViewModel e, quando o ViewModel diz, IsMenuActive = true (ou, no entanto), a animação para isso ocorre. Agora, com isso dito eu quero fazer outro ponto REALMENTE CLARO e POR FAVOR preste atenção. IsMenuActive provavelmente é um projeto BAD MVVM ou ViewModel. Ao projetar um ViewModel, você nunca deve assumir que um View terá algum recurso e apenas passa o estado do modelo traduzido. Dessa forma, se você decidir alterar sua Visualização para remover o Menu e apenas mostrar os dados / opções de outra maneira, o ViewModel não se importará. Então, como você gerencia o menu? Quando os dados fazem sentido, é assim. Portanto, uma maneira de fazer isso é fornecer ao Menu uma lista de opções (provavelmente uma matriz de ViewModels internos). Se essa lista tiver dados, o Menu saberá abrir através do gatilho; caso contrário, ele saberá se esconder através do gatilho. Você simplesmente possui dados para o menu ou não no ViewModel. NÃO decida mostrar / ocultar esses dados no ViewModel. simplesmente traduza o estado do modelo. Dessa forma, o View é completamente reativo e genérico e pode ser usado em muitas situações diferentes.

Tudo isso provavelmente não faz absolutamente nenhum sentido, se você ainda não está familiarizado com a arquitetura de cada uma, e aprender isso pode ser muito confuso, pois você encontrará muita informação ruim na rede.

Então ... coisas para ter em mente para acertar. Decida com antecedência como projetar seu aplicativo e entre em contato com ele.

Se você usa o MVC, o que é ótimo, verifique se o Controller é gerenciável e tem total controle da sua exibição. Se você tiver uma visão grande, considere adicionar controles à visão que possuem controladores diferentes. APENAS NÃO coloque esses controladores em cascata em controladores diferentes. Muito frustrante de manter. Reserve um momento e projete as coisas separadamente de uma maneira que funcione como componentes separados ... E sempre deixe o Controlador dizer ao Modelo para confirmar ou manter o armazenamento. A configuração de dependência ideal para o MVC é: View ← Controller → Model ou com ASP.NET (não me inicie) Model ← View ↔ Controller → Model (onde o Model pode ser o mesmo ou um modelo totalmente diferente de Controller para View)... é claro que a única necessidade de conhecer o Controller in View neste momento é principalmente para referência de endpoint para saber onde voltar para passar um modelo.

Se você faz MVVM, eu abençoo sua alma gentil, mas reserve um tempo para fazê-lo CERTO! Não use interfaces para um. Deixe sua visualização decidir como será a aparência com base em valores. Brinque com os dados do View with Mock. Se você acabar tendo uma Visualização que mostra um Menu (como no exemplo), mesmo que você não a desejasse na época, BOM. Sua visão está funcionando como deveria e reagindo com base nos valores como deveria. Basta adicionar mais alguns requisitos ao seu gatilho para garantir que isso não ocorra quando o ViewModel estiver em um determinado estado traduzido ou comandar o ViewModel para esvaziar esse estado. No seu ViewModel, NÃO remova isso com lógica interna, como se você estivesse decidindo a partir daí se o View deveria ou não vê-lo. Lembre-se de que você não pode assumir que exista um menu ou não no ViewModel. E finalmente, o modelo deve permitir que você altere e provavelmente o estado da loja. É aqui que a validação e tudo ocorrerá; por exemplo, se o modelo não puder modificar o estado, ele simplesmente será sinalizado como sujo ou algo assim. Quando o ViewModel perceber isso, ele traduzirá o que está sujo, e o View perceberá isso e mostrará algumas informações através de outro gatilho. Todos os dados no View podem ser vinculados ao ViewModel, para que tudo possa ser dinâmico, apenas o Model e o ViewModel não têm absolutamente nenhuma idéia de como o View reagirá à ligação. Por uma questão de fato, o Model também não tem idéia de um ViewModel. Ao configurar dependências, elas devem apontar assim e somente assim Se você modificar o estado, simplesmente se exibirá sujo ou algo assim. Quando o ViewModel perceber isso, ele traduzirá o que está sujo, e o View perceberá isso e mostrará algumas informações através de outro gatilho. Todos os dados no View podem ser vinculados ao ViewModel, para que tudo possa ser dinâmico, apenas o Model e o ViewModel não têm absolutamente nenhuma idéia de como o View reagirá à ligação. Por uma questão de fato, o Model também não tem idéia de um ViewModel. Ao configurar dependências, elas devem apontar assim e somente assim Se você modificar o estado, simplesmente se exibirá sujo ou algo assim. Quando o ViewModel perceber isso, ele traduzirá o que está sujo, e o View perceberá isso e mostrará algumas informações através de outro gatilho. Todos os dados no View podem ser vinculados ao ViewModel, para que tudo possa ser dinâmico, apenas o Model e o ViewModel não têm absolutamente nenhuma idéia de como o View reagirá à ligação. Por uma questão de fato, o Model também não tem idéia de um ViewModel. Ao configurar dependências, elas devem apontar assim e somente assim Todos os dados no View podem ser vinculados ao ViewModel, para que tudo possa ser dinâmico, apenas o Model e o ViewModel não têm absolutamente nenhuma idéia de como o View reagirá à ligação. Por uma questão de fato, o Model também não tem idéia de um ViewModel. Ao configurar dependências, elas devem apontar assim e somente assim Todos os dados no View podem ser vinculados ao ViewModel para que tudo possa ser dinâmico, apenas o Model e o ViewModel não têm absolutamente nenhuma idéia de como o View reagirá à ligação. Por uma questão de fato, o Model também não tem idéia de um ViewModel. Ao configurar dependências, elas devem apontar assim e somente assimExibir → ViewModel → Modelo (e uma nota lateral aqui ... e isso provavelmente será discutido também, mas eu não me importo ... NÃO PASSE O MODELO para o VIEW, a menos que esse MODELO seja imutável; caso contrário, envolva-o com um ViewModel adequado. O View não deve ver um período de modelo. Dou aos ratos que decifram a demonstração que você viu ou como fez, isso está errado.)

Aqui está minha dica final ... Veja um aplicativo MVC bem projetado, mas muito simples, e faça o mesmo para um aplicativo MVVM. Um terá mais controle com flexibilidade limitada a zero, enquanto o outro não terá controle e flexibilidade ilimitada.

Um ambiente controlado é bom para gerenciar o aplicativo inteiro a partir de um conjunto de controladores ou (uma única fonte), enquanto um ambiente reativo pode ser dividido em repositórios separados sem absolutamente nenhuma idéia do que o restante do aplicativo está fazendo. Gerenciamento micro versus gerenciamento gratuito.

Se não o confundi o suficiente, tente entrar em contato comigo ... Não me importo de analisar isso detalhadamente com ilustração e exemplos.

No final do dia, somos todos programadores e, com essa anarquia, vive dentro de nós ao codificar ... Então, as regras serão quebradas, as teorias mudarão, e tudo isso acabará sendo uma loucura ... Mas ao trabalhar em grandes projetos e em grandes equipes, realmente ajuda a concordar com um padrão de design e aplicá-lo. Um dia, os pequenos passos extras dados no início se transformarão em trancos e barrancos de economia depois.

Michael Puckett II
fonte
Resposta incrivelmente detalhada e precisa! Tornou claro para mim. :-)
ankush981
"Aprender isso pode ser muito confuso, pois você encontrará MUITAS informações ruins na rede". Sim. Como alguém que parece ter muita experiência com esses padrões de design, conhece algum bom tutorial / guia?
MarcelCheese
1
Para ser sincero, meu conhecimento em MVVM passou por anos ou tentativa e erro e o uso / execução de várias maneiras com base nos esforços da equipe. Recentemente (há 2 anos), pude colocar minha própria experiência em um plano de jogo resumido e liderar uma equipe a começar a terminar o processo, e fomos extremamente bem-sucedidos. Dito isto, não posso apontar você para nenhum lugar e pedir desculpas. Posso dizer que você está correto, por causa das várias opiniões, é muito confuso, mas, na IMO, com o MVVM, deve ser o mais genérico possível. ViewModels make capazes de permitir vistas para ligar e trabalhar com dados estritamente mas para qualquer ponto de vista ...
Michael Puckett II
1
Em outras palavras, NUNCA faça com que o ViewModel assuma que um View terá aparência ou ação de qualquer forma. ViewModel, para mim, é melhor usado como uma API, mas com comunicação estrita. Siga o plano de jogo para vincular, editar, comandar etc. Se o View precisar de lógica extra para funcionar de uma maneira específica, isso não tem nada a ver com o aplicativo ou dados (como uma animação ou uma caixa suspensa ..), então essa lógica pertence à camada View em algum lugar de alguma forma. Novamente, há uma infinidade de opiniões e isso é apenas meu, mas eu tenho uma sólida formação aqui e um sólido histórico até agora.
Michael Puckett II
Eu tenho aplicativos de exemplo que não me importo de compartilhar e que não me importo de criar um programa simples e contar para você ou qualquer outra pessoa, se quiser ou estiver curioso.
Michael Puckett II
23

Diferença simples: (Inspirado no curso Coursera AngularJS de Yaakov)

insira a descrição da imagem aqui

MVC (Model View Controller)

  1. Modelos: os modelos contêm informações de dados. Não chama ou usa o Controller and View. Contém a lógica de negócios e maneiras de representar dados. Alguns desses dados, de alguma forma, podem ser exibidos na exibição. Também pode conter lógica para recuperar os dados de alguma fonte.
  2. Controlador: atua como a conexão entre a vista e o modelo. Ver chamadas Controller e Controller chama o modelo. Basicamente, informa o modelo e / ou a visualização para alterar conforme apropriado.
  3. Ver: lida com a parte da interface do usuário. Interage com o usuário.

MVVM (Model View View Model)

ViewModel :

  1. É a representação do estado da vista.
  2. Ele mantém os dados exibidos na exibição.
  3. Responde para visualizar eventos, também conhecido como lógica de apresentação.
  4. Chama outras funcionalidades para processamento de lógica de negócios.
  5. Nunca pede diretamente à exibição para exibir qualquer coisa.
Pritam Banerjee
fonte
18

MVVM é um refinamento (discutível) do padrão Modelo de Apresentação . Digo discutível, porque a única diferença está em como o WPF fornece a capacidade de fazer ligação de dados e manipulação de comandos.

wekempf
fonte
1
Em 2009, essa resposta provavelmente foi boa, mas hoje não há debate, pois mesmo os controles HTML Helper da MSFT permitem a ligação usando os infames ajudantes "For". Knockout tem tudo a ver com ligação de dados no lado do cliente.
John Peters
1
Eu afirmei isso em 2009, porque muitas pessoas na comunidade aceitaram essa resposta. Eu disse que era discutível, porque MVVM e Presentation Model realmente são o mesmo padrão por nomes diferentes. Tanques para a popularidade no WPF, muitas vezes é chamado MVVM em outras estruturas hoje em dia, mas qualquer um dos nomes é preciso.
27617 wekempf
15

O viewmodel é um modelo "abstrato" para os elementos da interface do usuário. Ele deve permitir que você execute os comandos e ações em sua exibição de maneira não visual (por exemplo, para testá-lo).

Se você trabalhou com o MVC, provavelmente já achou útil criar objetos de modelo para refletir o estado da sua exibição, por exemplo, mostrar e ocultar alguma caixa de diálogo de edição, etc. Nesse caso, você está usando um modelo de exibição.

O padrão MVVM é simplesmente a generalização dessa prática para todos os elementos da UI.

E não é um padrão da Microsoft, o que se acrescenta é que as ligações de dados do WPF / Silverlight são especialmente adequadas para trabalhar com esse padrão. Mas nada impede você de usá-lo com faces de servidor java, por exemplo.

DaniCE
fonte
13

As outras respostas podem não ser fáceis de entender para quem não está muito familiarizado com o assunto dos padrões arquiteturais. Alguém que é novo na arquitetura de aplicativos pode querer saber como sua escolha pode afetar seu aplicativo na prática e o que todo esse barulho é nas comunidades.

Tentando esclarecer o que foi exposto, criei esse roteiro envolvendo MVVM, MVP e MVC. A história começa com um usuário clicando no botão 'FIND' em um aplicativo de pesquisa de filmes…:

Usuário: Clique em…

Ver : Quem é esse? [ MVVM | MVP | MVC ]

Usuário: Acabei de clicar no botão de pesquisa…

Ver : Ok, espere um segundo…. [ MVVM | MVP | MVC ]

( Vista chamando o ViewModel | Presenter | Controller …) [ MVVM | MVP | MVC ]

Exibir : Hey ViewModel | Apresentador | Controlador , um usuário acabou de clicar no botão de pesquisa, o que devo fazer? [ MVVM | MVP | MVC ]

ViewModel | Apresentador | Controlador : Hey View , existe algum termo de pesquisa nessa página? [ MVVM | MVP | MVC ]

Ver : Sim,… aqui está… “piano” [ MVVM | MVP | MVC ]

—— Essa é a diferença mais importante entre MVVM E MVP | MVC ———

Apresentador : Obrigado Ver , ... enquanto isso eu estou procurando-se o termo de pesquisa sobre o modelo , por favor, mostre a ele / ela uma barra de progresso [ MVP | MVC ]

( Apresentador | O controlador está chamando o modelo …) [ MVP | MVC ]

ViewController : Obrigado, procurarei o termo de pesquisa no modelo, mas não o atualizaremos diretamente. Em vez disso, acionarei eventos para searchResultsListObservable se houver algum resultado. Então é melhor você observar isso. [ MVVM ]

(Ao observar qualquer gatilho em searchResultsListObservable, o View acha que deve mostrar alguma barra de progresso para o usuário, pois o ViewModel não fala com ele sobre isso)

————————————————————————

ViewModel | Apresentador | Controlador : Hey Model , você tem alguma correspondência para este termo de pesquisa ?: "piano" [ MVVM | MVP | MVC ]

Modelo : Hey ViewModel | Apresentador | Controlador , deixe-me verificar… [ MVVM | MVP | MVC ]

(O modelo está fazendo uma consulta no banco de dados do filme…) [ MVVM | MVP | MVC ]

( Depois de um tempo … )

———— Este é o ponto divergente entre MVVM , MVP e MVC —————

Modelo : Encontrei uma lista para você, ViewModel | Apresentador , aqui está em JSON "[{" nome ":" Professor de piano "," ano ": 2001}, {" nome ":" Piano "," ano ": 1993}]" [ MVVM | MVP ]

Modelo : Há algum resultado disponível, Controlador. Eu criei uma variável de campo na minha instância e a preenchi com o resultado. Seu nome é "searchResultsList" [ MVC ]

( Presenter | Controller agradece ao Model e volta à View ) [ MVP | MVC ]

Apresentador : Obrigado pela espera do View , encontrei uma lista de resultados correspondentes e os organizei em um formato apresentável: ["Piano Teacher 2001 ″," Piano 1993 "]. Também oculte a barra de progresso agora [ MVP ]

Controlador : Obrigado por aguardar o View , perguntei ao Model sobre sua consulta de pesquisa. Ele diz que encontrou uma lista de resultados correspondentes e os armazenou em uma variável chamada "searchResultsList" dentro de sua instância. Você pode obtê-lo de lá. Também oculte a barra de progresso agora [ MVC ]

ViewModel : Qualquer observador em searchResultsListObservable será notificado de que existe esta nova lista no formato apresentável: ["Piano Teacher 2001", "Piano 1993"]. [ MVVM ]

Ver : Muito obrigado Apresentador [ MVP ]

Ver : Obrigado “ Controller ” [ MVC ] (Agora, o View está se questionando: como devo apresentar os resultados que recebo do modelo ao usuário? O ano de produção do filme deve ser o primeiro ou o último ...?)

Ver : Ah, há um novo gatilho em searchResultsListObservable…, bom, existe uma lista apresentável, agora só preciso mostrá-la em uma lista. Também devo ocultar a barra de progresso agora que tenho o resultado. [ MVVM ]

Caso você esteja interessado, escrevi uma série de artigos aqui , comparando MVVM, MVP e MVC implementando um aplicativo Android de pesquisa de filmes.

Ali Nem
fonte
Há uma ótima resposta em todo o texto de sabor aqui ... Com algumas formatações e discussões pequenas entre componentes, essa pode ser a melhor nesta página.
neonblitzer 13/03
10

Injetando ViewModels fortemente tipados na View usando MVC

  1. O controlador é responsável por atualizar o ViewModel e injetá-lo no View. (para obter solicitações)
  2. O ViewModel é o contêiner do DataContext e o estado da exibição, como o último item selecionado etc.
  3. O modelo contém entidades do banco de dados e é muito próximo ao esquema do banco de dados, ele faz as consultas e a filtragem. (Eu gosto de EF e LINQ para isso)
  4. O Modelo também deve considerar repositórios e / ou projeção de resultados em tipos fortes (EF possui um ótimo método ... EF.Database.Select (querystring, parms) para acesso direto ao ADO para injetar consultas e recuperar tipos fortes. é um argumento lento.O EF NÃO É LENTO !
  5. O ViewModel obtém os dados e executa as regras e validação de negócios
  6. O controlador na postagem de retorno chamará o método ViewModel Post e aguardará os resultados.
  7. O controlador injeta o Viewmodel recém-atualizado na View. O modo de exibição usa apenas ligação de tipo forte .
  8. A visualização apenas renderiza os dados e envia eventos de volta ao controlador. (veja exemplos abaixo)
  9. O MVC intercepta a solicitação de entrada e a encaminha para o controlador apropriado com um forte tipo de dados

Nesse modelo, não há mais contato no nível HTTP com os objetos de solicitação ou resposta, pois a máquina MVC da MSFT o oculta.

No esclarecimento do item 6 acima (a pedido) ...

Suponha um ViewModel como este:

public class myViewModel{
     public string SelectedValue {get;set;}
public void Post(){
    //due to MVC model binding the SelectedValue string above will be set by MVC model binding on post back.
    //this allows you to do something with it.
    DoSomeThingWith(SelectedValue);
    SelectedValue = "Thanks for update!";
 }
}

O método controlador da postagem será parecido com este (veja abaixo), observe que a instância do mvm é instanciada automaticamente pelos mecanismos de ligação do MVC. Você nunca precisa descer para a camada de string de consulta! Isso é o MVC que instancia o ViewModel para você com base nas cadeias de consulta!

[HTTPPOST]   
public ActionResult MyPostBackMethod (myViewModel mvm){
         if (ModelState.IsValid)
        {
               // Immediately call the only method needed in VM...
               mvm.Post()
        }
      return View(mvm);
}

Observe que, para que esse método de ação acima funcione como você pretende, você deve ter um CTOR nulo definido que inicialize as coisas que não foram retornadas na postagem. A postagem de retorno também deve postar de volta os pares nome / valor para as coisas que mudaram. Se faltam pares nome / valor, o mecanismo de ligação do MVC faz a coisa correta, que simplesmente não é nada! Se isso acontecer, você pode estar dizendo "Estou perdendo dados nas postagens" ...

A vantagem desse padrão é que o ViewModel faz todo o trabalho "desorganizado" em interface com a lógica Modelo / Negócio, o controlador é apenas um tipo de roteador. É o SOC em ação.

John Peters
fonte
Você pode esclarecer o item 6? Percebo que você está cobrindo apenas o ASP.Net, mas parece estar adicionando uma dependência indesejada ao ViewModel. (por exemplo, conhecimento de onde os dados vêm / vão). Um exemplo de código (pseudo-código?) Seria bom para esclarecer esta resposta e mostrar quais partes são do lado do servidor e quais são do lado do cliente.
Gone Coding
9

O MVVM adiciona o modelo de visualização ao mix. Isso é importante, pois permite que você use grande parte da abordagem de ligação do WPF, sem colocar todas as partes específicas da interface do usuário em seu modelo regular.

Posso estar errado, mas não tenho certeza se o MVVM realmente força o controlador na mistura. Acho que o conceito está mais alinhado com: http://martinfowler.com/eaaDev/PresentationModel.html . Eu acho que as pessoas escolhem combiná-lo com o MVC, não que ele esteja embutido no padrão.

eglasius
fonte
3
O MVVM, estritamente falando, é o Modelo de Apresentação, embora o MVVM esteja se tornando o nome preferido para a realização específica do padrão do WPF.
27410 wekempf
Acordado. O Viewmodel no MVC "IS" é a máquina de estado para a exibição. Ele contém o datacontext e rastreia todas as informações do item selecionado e também pode conter toda a lógica de validação usando a interface IValidatableObject. O ViewModel faz interface com o banco de dados na camada de modelo, que pode usar modelos de tipos fortes. MVVM no WPF É o controlador do MVC. Mas o controlador do MVC é muito mais limpo, é essencial um manipulador de roteamento.
John Peters
9

Pelo que posso dizer, o MVVM é mapeado para o MVC do MVC - o que significa que, em um padrão tradicional do MVC, o V não se comunica diretamente com o M. Na segunda versão do MVC, há um link direto entre M e V. MVVM parece pegar todas as tarefas relacionadas à comunicação M e V e associá-la para separá-la do C. Na verdade, ainda existe o fluxo de trabalho do aplicativo de escopo maior (ou implementação dos cenários de uso) que não são totalmente contabilizados no MVVM. Este é o papel do controlador. Ao remover esses aspectos de nível inferior dos controladores, eles são mais limpos e facilitam a modificação do cenário de uso do aplicativo e da lógica de negócios, tornando os controladores mais reutilizáveis.

se_thoughts
fonte
1
IMHO Eu diria que "fazer controladores mais reutilizável" é muito ampla uma declaração e contra-produtivo para os "controladores" gerais do ASP.NET (ou seja, não a camada de lógica de negócios) como esses controladores normalmente contêm as partes do aplicativo que são aplicação- específico . São as Views, Models, ViewModels e a lógica de negócios que precisam ser reutilizáveis. Eu pensaria que tratar os módulos da lógica de negócios como provedores de serviços, não como controladores, seria uma opção melhor.
Gone Coding
Mas você está falando sobre o "ViewModel" no Asp.net, não sobre o padrão de design do MVVM. Duas coisas diferentes
Luis
9

Surpreende-me que esta seja uma resposta altamente votada sem mencionar a origem da MVVM. MVVM é um termo popular usado na comunidade Microsoft e é originário do Modelo de Apresentação de Martin Fowler . Portanto, para entender o motivo do padrão e as diferenças com os outros, o artigo original sobre o padrão é a primeira coisa a ler.

Cheng
fonte
Uau ... então o MVC e o MVVM vieram do SmallTalk? Eles estavam muito à frente do seu tempo, aparentemente ...
Matte
Na verdade, dizer que se originou do Modelo de Apresentação de Martin Fowler não é exato. É muito difícil determinar o que veio primeiro, mas os dois padrões (permitindo que eles sejam realmente o mesmo padrão) foram alcançados de forma independente e aproximadamente ao mesmo tempo.
27417 wekempf
6

Bem, geralmente o MVC é usado no desenvolvimento da Web e o MVVM é mais popular no desenvolvimento do WPF / Silverlight. No entanto, às vezes o architecute da web pode ter uma mistura de MVC e MVVM.

Por exemplo: você pode usar o knockout.js e, nesse caso, terá o MVVM no seu lado do cliente. E o lado do servidor do seu MVC também pode mudar. Nos aplicativos complexos, ninguém usa o modelo puro. Pode ser sensato usar um ViewModel como um "Modelo" do MVC e seu Modelo real basicamente fará parte dessa VM. Isso fornece uma camada extra de abstração.

Rinat Galyautdinov
fonte
O que 'desenvolvimento da web' denomina 'MVC' nada mais é do que separação de preocupações e não o MVC autêntico que precedeu a web.
Terrence Brannon
4

MVVMC, ou talvez MVC +, parece ser uma abordagem viável para empresas, bem como para o rápido desenvolvimento de aplicativos. Embora seja bom separar a interface do usuário da lógica de negócios e de interação, o padrão MVVM 'puro' e os exemplos mais disponíveis funcionam melhor em visualizações únicas.

Não tenho certeza sobre seus projetos, mas a maioria dos meus aplicativos contém páginas e várias visualizações (reutilizáveis) e, portanto, os ViewModels precisam interagir até certo ponto. Usar a página como controlador anularia completamente o objetivo do MVVM, portanto, não usar uma abordagem "VM-C" para a lógica subjacente pode resultar em ... bem ... construções desafiadoras à medida que o aplicativo amadurece. Mesmo no VB-6, a maioria de nós provavelmente parou de codificar a lógica de negócios no evento Button e começou a 'retransmitir' comandos para um controlador, certo? Recentemente, observei muitos framworks emergentes sobre esse tópico; meu favorito é claramente a abordagem de Magalhães (no codeplex). Feliz codificação!

http://en.wikipedia.org/wiki/Model_View_ViewModel#References

der Martin
fonte
4

O Controller não é substituído por um ViewModel no MVVM, porque o ViewModel possui uma funcionalidade totalmente diferente da do Controller. Você ainda precisa de um Controller, porque sem um Controller seu Model, ViewModel e View não farão muito ... No MVVM você também tem um Controller, o nome MVVM é apenas enganoso.

MVVMC é o nome correto na minha humilde opinião.

Como você pode ver, o ViewModel é apenas uma adição ao padrão MVC. Ele move a lógica de conversão (por exemplo, converter objeto em uma string) do Controller para o ViewModel.

Ini
fonte
4

Eu fiz um artigo médio para isso.

MVVM

  1. Exibir ➡ ViewModel ➡ Modelo

    • A visualização tem uma referência ao ViewModel, mas não vice-versa.
    • O ViewModel tem uma referência ao modelo, mas não vice-versa.
    • O View não tem referência ao modelo e vice-versa.
  2. Se você estiver usando um controlador, ele pode ter uma referência para Visualizações e ViewModels , apesar de um controlador não é sempre necessário, como demonstrado no SwiftUI .

  3. Ligação de dados : criamos ouvintes para as propriedades do ViewModel.
class CustomView: UIView {
  var viewModel = MyViewModel {
    didSet {
      self.color = viewModel.color
    }
  }

  convenience init(viewModel: MyViewModel) {
    self.viewModel = viewModel
  }
}


struct MyViewModel {
   var viewColor: UIColor {
      didSet {
         colorChanged?() // This is where the binding magic happens.
      }
   }

   var colorChanged: ((UIColor) -> Void)?
}


class MyViewController: UIViewController {

   let myViewModel = MyViewModel(viewColor: .green)
   let customView: CustomView!

   override func viewDidLoad() {
      super.viewDidLoad()

      // This is where the binder is assigned.
      myViewModel.colorChanged = { [weak self] color in 
        print("wow the color changed")
      }
      customView = CustomView(viewModel: myViewModel)
      self.view = customView
   }
}

diferenças na configuração

  1. A lógica de negócios é mantida no controlador para MVC e no ViewModels para MVVM.
  2. Os eventos são transmitidos diretamente da View para o controlador no MVC, enquanto os eventos são transmitidos da View para o ViewModel para o Controller (se houver um) do MVVM.

Características comuns

  1. O MVVM e o MVC não permitem que o View envie mensagens diretamente para os modelos.
  2. Ambos têm modelos.
  3. Ambos têm vistas.

Vantagens do MVVM

  1. Como os ViewModels mantêm a lógica comercial, eles são objetos concretos menores, facilitando os testes de unidade. Por outro lado, no MVC, a lógica de negócios está no ViewController. Como você pode confiar que um teste de unidade de um controlador de exibição é abrangente e seguro sem testar todos os métodos e ouvintes simultaneamente? Você não pode confiar totalmente nos resultados do teste de unidade.
  2. No MVVM, como a lógica de negócios é desviada do Controller para unidades atômicas do ViewModel, o tamanho do ViewController diminui e isso torna o código do ViewController mais legível.

Vantagens do MVC

  1. O fornecimento de lógica de negócios no controlador reduz a necessidade de ramificação e, portanto, é mais provável que as instruções sejam executadas no cache, que é mais eficiente em encapsular a lógica de negócios no ViewModels.
  2. Fornecer lógica de negócios em um só lugar pode acelerar o processo de desenvolvimento de aplicativos simples, onde os testes não são necessários. Não sei quando os testes não são necessários.
  3. É mais fácil pensar na lógica de negócios no ViewController para novos desenvolvedores.
ScottyBlades
fonte
1
Melhor explicação
p32094 23/03
2

Do ponto de vista prático, o MVC (Model-View-Controller) é um padrão. No entanto, o MVC, quando usado como ASP.net MVC, quando combinado com o Entity Framework (EF) e as "ferramentas de poder" é uma abordagem muito poderosa e parcialmente automatizada para trazer bancos de dados, tabelas e colunas para uma página da Web, para Operações CRUD ou apenas operações R (recuperar ou ler). Pelo menos enquanto eu usava o MVVM, o View Models interagia com modelos que dependiam de objetos de negócios, que eram "feitos à mão" e, depois de muito esforço, tivemos a sorte de obter modelos tão bons quanto o que a EF oferece " da caixa ". Do ponto de vista prático da programação, o MVC parece ser uma boa opção, pois oferece uma grande quantidade de utilidade pronta para uso, mas ainda existe a possibilidade de adicionar sinos e assobios.

JosephDoggie
fonte
2

Como complemento de muitas das respostas dadas, eu gostaria de adicionar uma perspectiva adicional da Web moderna do lado do cliente - ou do ponto de vista de Rich Web Application .

Atualmente, sites simples e aplicativos maiores são geralmente criados com muitas bibliotecas populares, como o Bootstrap. Construído por Steve Sanderson, o Knockout fornece suporte para o padrão MVVM, que imita um dos comportamentos mais importantes no padrão: ligação de dados por meio do modelo de exibição. Com um pouco de JavaScript, dados e lógica podem ser implementados que podem ser adicionados aos elementos da página com data-bindatributos HTML simples , semelhante ao uso de muitos dos recursos do Bootstrap . Juntas, essas duas bibliotecas sozinhas oferecem conteúdo interativo; e quando combinada com o roteamento, essa abordagem pode resultar em uma abordagem simples, porém poderosa, para a criação do Aplicativo de Página Única .

Da mesma forma, uma estrutura moderna do lado do cliente, como Angular, segue o padrão MVC por convenção, mas também adiciona um serviço. Curiosamente, é apresentado como Model-View-Whatever (MVW). (Veja esta postagem no Stack Overflow .)

Além disso, com o surgimento de estruturas da Web Progressivas , como o Angular 2, estamos vendo uma mudança na terminologia e talvez um novo padrão arquitetural em que os Componentes compreendem uma Visualização ou Modelo e interagem com um Serviço - todos os quais podem estar contidos em um Módulo; e uma série de módulos compõe o aplicativo.

Richard Nalezynski
fonte
2

Eu costumava pensar que MVC e MVVM são os mesmos. Agora, devido à existência do Flux, posso dizer a diferença:

No MVC, para cada visualização em seu aplicativo, você tem um modelo e um controlador, então eu chamaria isso de view, view model, view controller. O padrão não mostra como uma visualização pode se comunicar com outra. Portanto, em estruturas diferentes, existem implementações diferentes para isso. Por exemplo, existem implementações em que os controladores conversam entre si, enquanto em outras implementações há outro componente que medeia entre eles. Existem até implementações nas quais os modelos de visualização se comunicam entre si, o que é uma quebra do padrão MVC porque o modelo de visualização deve ser acessado apenas pelo controlador de visualização.

No MVVM, você também tem um modelo de visualização para cada componente. O padrão não especifica como diabos a visualização deve influenciar o modelo de visualização; portanto, geralmente a maioria das estruturas inclui apenas a funcionalidade do controlador no modelo de visualização. No entanto, o MVVM diz que os dados do seu modelo de visualização devem vir do modelo, que é o modelo inteiro que não está ciente ou customizado para uma visualização específica.

Para demonstrar a diferença, vamos usar o padrão Flux. O padrão de fluxo informa como diferentes visões no aplicativo devem se comunicar. Cada visualização ouve uma loja e aciona ações usando o expedidor. O despachante, por sua vez, informa todas as lojas sobre a ação que acabou de ser realizada e as lojas se atualizam. Uma loja no Flux corresponde ao modelo (geral) no MVVM. não é personalizado para nenhuma visualização específica. Geralmente, quando as pessoas usam React e Flux, cada componente React realmente implementa o padrão MVVM. Quando uma ação ocorre, o modelo de visualização chama o expedidor e, finalmente, é atualizado de acordo com as alterações na loja, que é o modelo. Você não pode dizer que cada componente implementa o MVC porque no MVC apenas o controlador pode atualizar o modelo de visualização.

Alon
fonte
2

O mvc é do lado do servidor e o mvvm é do lado do cliente (navegador) no desenvolvimento da web.

na maioria das vezes o javascript é usado para mvvm no navegador. existem muitas tecnologias do lado do servidor para o mvc.

Maulik Gangani
fonte
1

Em pouco tempo, o MVC Controler está ciente da exibição (controles), enquanto no MVVM, o ViewModel não sabe quem o consome. O ViewModel expõe suas propriedades e ações observáveis ​​a quem estiver interessado em usá-lo. Esse fato facilita o teste, pois não há referência à interface do usuário no ViewModel.

daneejela
fonte
1

Model-View-Controller (geralmente conhecido como MVC ) é um padrão de design de software comumente usado para desenvolver interfaces de usuário que dividem a lógica do programa relacionado em três elementos interconectados. Isso é feito para separar representações internas de informações das formas como as informações são apresentadas e aceitas pelo usuário. Seguindo o padrão arquitetural do MVC, os componentes principais são dissociados, permitindo a reutilização de código e o desenvolvimento paralelo.

Tradicionalmente usado para interfaces gráficas de usuário (GUIs) da área de trabalho, esse padrão se tornou popular no design de aplicativos da web. Linguagens de programação populares como JavaScript, Python, Ruby, PHP, Java e C # têm estruturas MVC que são usadas no desenvolvimento de aplicativos da Web imediatamente.

Modelo

O componente central do padrão. É a estrutura de dados dinâmicos do aplicativo, independente da interface do usuário. Ele gerencia diretamente os dados, lógica e regras do aplicativo.

Visão

Qualquer representação de informações como um gráfico, diagrama ou tabela. São possíveis várias visualizações da mesma informação, como um gráfico de barras para gerenciamento e uma exibição tabular para contadores.

Controlador

Aceita entrada e a converte em comandos para o modelo ou exibição.

Além de dividir o aplicativo nesses componentes, o design do modelo-visualização-controlador define as interações entre eles.

O modelo é responsável por gerenciar os dados do aplicativo. Ele recebe a entrada do usuário do controlador.

A visualização significa uma apresentação do modelo em um formato específico.

O controlador responde à entrada do usuário e executa interações nos objetos do modelo de dados. O controlador recebe a entrada, opcionalmente a valida e depois passa a entrada para o modelo. insira a descrição da imagem aqui

Model-View-ViewModel (MVVM) é um padrão de arquitetura de software.

O MVVM facilita a separação do desenvolvimento da interface gráfica do usuário - seja através de uma linguagem de marcação ou código da GUI - do desenvolvimento da lógica de negócios ou da lógica de back-end (o modelo de dados). O modelo de visualização do MVVM é um conversor de valor, o que significa que o modelo de visualização é responsável por expor (converter) os objetos de dados do modelo de forma que os objetos sejam gerenciados e apresentados com facilidade. Nesse aspecto, o modelo de vista é mais modelo que uma vista e lida com a maioria, se não com toda a lógica de exibição da vista. O modelo de visualização pode implementar um padrão mediador, organizando o acesso à lógica de back-end em torno do conjunto de casos de uso suportados pela visualização.

O MVVM é uma variação do padrão de design do Modelo de apresentação de Martin Fowler. O MVVM abstrai o estado e o comportamento de uma exibição da mesma maneira, mas um Modelo de Apresentação abstrai uma exibição (cria um modelo de exibição) de uma maneira que não depende de uma plataforma específica da interface com o usuário.

O MVVM foi inventado pelos arquitetos da Microsoft Ken Cooper e Ted Peters especificamente para simplificar a programação de interfaces de usuário orientada a eventos. O padrão foi incorporado ao Windows Presentation Foundation (WPF) (sistema de gráficos .NET da Microsoft) e ao Silverlight (derivado de aplicativos da Internet do WPF). John Gossman, um dos arquitetos WPF e Silverlight da Microsoft, anunciou o MVVM em seu blog em 2005.

Model-View-ViewModel também é conhecido como model-view-finder, especialmente em implementações que não envolvem a plataforma .NET. O ZK (uma estrutura de aplicativo da Web escrita em Java) e o KnockoutJS (uma biblioteca JavaScript) usam o fichário de visualização de modelo. insira a descrição da imagem aqui

Rahul
fonte