design-patterns - versus - mvp padrao de projeto




O que são MVP e MVC e qual é a diferença? (16)

Ao olhar para além da maneira RAD (arrastar e soltar e configurar) de criar interfaces de usuário, muitas ferramentas incentivam a probabilidade de você encontrar três padrões de design chamados Model-View-Controller , Model-View-Presenter e Model-View-ViewModel . Minha pergunta tem três partes:

  1. Quais problemas esses padrões abordam?
  2. Como eles são semelhantes?
  3. Como eles são diferentes?

Model-View-Presenter

No MVP , o Presenter contém a lógica comercial da interface do usuário para a exibição. Todas as chamadas do View são delegadas diretamente ao Presenter. O apresentador também é dissociado diretamente da exibição e conversa com ele por meio de uma interface. Isso é para permitir zombar da exibição em um teste de unidade. Um atributo comum do MVP é que deve haver muitos despachos bidirecionais. Por exemplo, quando alguém clica no botão "Salvar", o manipulador de eventos delega ao método "OnSave" do Presenter. Após a conclusão do salvamento, o Apresentador retornará a Visualização através de sua interface, para que a Visualização possa exibir que a gravação foi concluída.

O MVP tende a ser um padrão muito natural para obter apresentações separadas em Web Forms. O motivo é que o modo de exibição é sempre criado primeiro pelo tempo de execução do ASP.NET. Você pode descobrir mais sobre as duas variantes .

Duas variações primárias

Visão passiva: a visão é o mais burra possível e contém lógica quase nula. O apresentador é um intermediário que fala com a View e o Model. A Vista e o Modelo são completamente protegidos um do outro. O Modelo pode gerar eventos, mas o Apresentador os assina para atualizar a Visualização. Na Visualização Passiva, não há ligação direta aos dados. Em vez disso, a Visualização expõe as propriedades do setter que o Presenter usa para definir os dados. Todo o estado é gerenciado no Presenter e não na View.

  • Pro: superfície máxima de testabilidade; separação limpa da Vista e do Modelo
  • Con: mais trabalho (por exemplo, todas as propriedades do setter), como você mesmo faz com todos os dados.

Controlador de supervisão: o apresentador lida com gestos do usuário. A Visualização se liga ao Modelo diretamente através da ligação de dados. Nesse caso, é tarefa do apresentador transmitir o modelo para a visualização para que ele possa se vincular a ele. O apresentador também conterá lógica para gestos, como pressionar um botão, navegação etc.

  • Pro: aproveitando a ligação de dados, a quantidade de código é reduzida.
  • Contras: há menos superfície testável (por causa da ligação de dados) e há menos encapsulamento no View, pois ele fala diretamente com o Model.

Model-View-Controller

No MVC , o Controlador é responsável por determinar qual Visualização exibir em resposta a qualquer ação, incluindo quando o aplicativo é carregado. Isso difere do MVP, onde as ações são roteadas pela tela para o apresentador. No MVC, toda ação na Visualização se correlaciona com uma chamada para um Controller junto com uma ação. Na web, cada ação envolve uma chamada para uma URL do outro lado da qual existe um Controller que responde. Depois que o Controlador concluir seu processamento, ele retornará a Visualização correta. A sequência continua dessa maneira ao longo da vida do aplicativo:

    Action in the View
        -> Call to Controller
        -> Controller Logic
        -> Controller returns the View.

Outra grande diferença sobre o MVC é que o View não se liga diretamente ao modelo. A visualização é renderizada e é completamente sem estado. Nas implementações do MVC, o View geralmente não possui lógica no código por trás. Isso é contrário ao MVP, onde é absolutamente necessário porque, se o View não delegar ao Presenter, ele nunca será chamado.

Modelo de Apresentação

Um outro padrão a ser observado é o padrão do Modelo de Apresentação . Nesse padrão, não há apresentador. Em vez disso, o modo de exibição vincula diretamente a um modelo de apresentação. O modelo de apresentação é um modelo criado especificamente para a visualização. Isso significa que este modelo pode expor propriedades que nunca seriam colocadas em um modelo de domínio, pois isso seria uma violação da separação de preocupações. Nesse caso, o modelo de apresentação vincula-se ao modelo de domínio e pode assinar eventos provenientes desse modelo. O modo de exibição se inscreve em eventos provenientes do modelo de apresentação e se atualiza de acordo. O modelo de apresentação pode expor comandos que a exibição usa para chamar ações. A vantagem dessa abordagem é que você pode essencialmente remover completamente o code-behind, pois o PM encapsula completamente todo o comportamento da exibição. Esse padrão é um candidato muito forte para uso em aplicativos WPF e também é chamado de Model-View-ViewModel .

Há um artigo do MSDN sobre o Modelo de Apresentação e uma seção no Composite Application Guidance for WPF (antigo Prism) sobre Padrões de Apresentação Separados


MVP: a visualização está no comando.

A visualização, na maioria dos casos, cria seu apresentador. O apresentador irá interagir com o modelo e manipular a visualização por meio de uma interface. Às vezes, a exibição interage com o apresentador, geralmente através de alguma interface. Isso se resume à implementação; você deseja que a exibição chame métodos no apresentador ou deseja que a exibição tenha eventos que o apresentador escuta? Tudo se resume a isso: a visão conhece o apresentador. A exibição delega ao apresentador.

MVC: o controlador está no comando.

O controlador é criado ou acessado com base em algum evento / solicitação. O controlador cria a visualização apropriada e interage com o modelo para configurar ainda mais a visualização. Tudo se resume a: o controlador cria e gerencia a exibição; a vista é escrava do controlador. A vista não sabe sobre o controlador.


Ambos são padrões que tentam separar a apresentação e a lógica de negócios, dissociando a lógica de negócios dos aspectos da interface do usuário

Arquiteturalmente, o MVP é uma abordagem baseada no Controlador de Página, onde o MVC é uma abordagem baseada no Front Controller. Isso significa que, no MVP, o ciclo de vida da página do formulário da Web é aprimorado, extraindo a lógica de negócios do código anterior. Em outras palavras, é a página que atende a solicitação http. Em outras palavras, o MVP IMHO é o tipo evolutivo de aprimoramento de formulário da Web. O MVC, por outro lado, muda completamente o jogo porque a solicitação é interceptada pela classe do controlador antes que a página seja carregada, a lógica de negócios é executada lá e, no resultado final do controlador, processando os dados despejados na página ("visualização"). Nesse sentido, o MVC parece (pelo menos para mim) muito o sabor do MVP do Supervising Controller aprimorado com o mecanismo de roteamento

Ambos permitem TDD e têm desvantagens e desvantagens.

A decisão sobre como escolher um deles IMHO deve basear-se em quanto tempo se investiu no tipo de formulário da Web ASP NET de desenvolvimento da web. Se alguém se considera bom em formulários da web, sugiro MVP. Se alguém não se sentir tão à vontade em coisas como o ciclo de vida da página, etc, o MVC pode ser um caminho a percorrer aqui.

Aqui está outro link de postagem no blog, fornecendo um pouco mais de detalhes sobre este tópico

http://blog.vuscode.com/malovicn/archive/2007/12/18/model-view-presenter-mvp-vs-model-view-controller-mvc.aspx


Aqui estão ilustrações que representam o fluxo de comunicação




Essa é uma simplificação excessiva das muitas variantes desses padrões de design, mas é assim que eu gosto de pensar sobre as diferenças entre os dois.

MVC

MVP


Eu escrevi sobre isso há algum tempo, citando o excelente post de Todd Snyder sobre a diferença entre os dois :

Aqui estão as principais diferenças entre os padrões:

Padrão MVP

  • A vista é mais fracamente acoplada ao modelo. O apresentador é responsável por vincular o modelo à visualização.
  • Teste de unidade mais fácil porque a interação com a visualização é feita através de uma interface
  • Geralmente, visualize o mapa do apresentador um a um. Visualizações complexas podem ter vários apresentadores.

Padrão MVC

  • Controladores são baseados em comportamentos e podem ser compartilhados entre visualizações
  • Pode ser responsável por determinar qual visualização exibir

É a melhor explicação na web que eu poderia encontrar.


Existem muitas respostas para a pergunta, mas senti que é necessário uma resposta realmente simples comparando claramente as duas. Aqui está a discussão que inventei quando um usuário procura um nome de filme em um aplicativo MVP e MVC:

Usuário: Clique em…

Ver : quem é esse? [ MVP | MVC ]

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

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

( Exibir chamando o Presenter | Controller …) [ MVP | MVC ]

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

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

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

Apresentador : Obrigado,… Enquanto isso, procurando o termo de pesquisa no modelo , mostre a ele uma barra de progresso [ MVP | MVC ]

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

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

Modelo : Hey Presenter | Controlador , deixe-me verificar… [ MVP | MVC ]

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

( Depois de um tempo ... )

-------------- É aqui que o MVP e o MVC começam a divergir ---------------

Modelo : Encontrei uma lista para você, apresentador , aqui está em JSON “[{" name ":" Piano Teacher "," year ": 2001}, {" name ":" Piano "," year ": 1993} ] ”[ 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"]. Por favor, mostre-o ao usuário em uma lista vertical. 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 ]

Ver : Muito obrigado Apresentador [ MVP ]

Ver : Obrigado "Controller" [ MVC ] (Agora, o View está se questionando: como devo apresentar os resultados do modelo para o usuário? O ano de produção do filme deve ser o primeiro ou o último ...? estar em uma lista vertical ou horizontal? ...)

Caso você esteja interessado, escrevi uma série de artigos que tratam de padrões de arquitetura de aplicativos (MVC, MVP, MVVP, arquitetura limpa, ...) acompanhados por um repositório do Github here . Mesmo que a amostra seja escrita para o Android, os princípios subjacentes podem ser aplicados a qualquer meio.


No MVP, a visualização extrai dados do apresentador, que extrai e prepara / normaliza dados do modelo, enquanto no MVC o controlador extrai dados do modelo e do conjunto, pressionando a visualização.

No MVP, você pode ter uma única visualização trabalhando com vários tipos de apresentadores e um único apresentador trabalhando com diferentes visualizações.

O MVP geralmente usa algum tipo de estrutura de ligação, como a estrutura de ligação do Microsoft WPF ou várias estruturas de ligação para HTML5 e Java.

Nessas estruturas, a UI / HTML5 / XAML está ciente de quais propriedades do apresentador cada elemento da interface do usuário exibe; portanto, quando você vincula uma visualização a um apresentador, a visualização procura as propriedades e sabe como extrair dados delas e como para defini-los quando um valor é alterado na interface do usuário pelo usuário.

Portanto, se, por exemplo, o modelo é um carro, o apresentador é uma espécie de apresentador de carro, expõe as propriedades do carro (ano, fabricante, assentos etc.) à exibição. A visualização sabe que o campo de texto chamado 'fabricante de carros' precisa exibir a propriedade Criador do apresentador.

Em seguida, você pode vincular à visualização muitos tipos diferentes de apresentador, todos devem ter a propriedade Maker - ela pode ser de avião, trem ou qualquer outra coisa, a visualização não se importa. A visualização extrai dados do apresentador - não importa qual - desde que implemente uma interface acordada.

Essa estrutura de ligação, se você a reduzir, é na verdade o controlador :-)

E assim, você pode ver no MVP como uma evolução do MVC.

MVC é ótimo, mas o problema é que geralmente o seu controlador por visualização. O Controlador A sabe como definir os campos da Vista A. Se agora, você deseja que a Vista A exiba dados do modelo B, você precisa do Controlador A para conhecer o modelo B ou precisa do Controlador A para receber um objeto com uma interface - como MVP apenas sem as ligações, ou você precisa reescrever o código do conjunto de UI no Controlador B.

Conclusão - O MVP e o MVC são ambos dissociados dos padrões da interface do usuário, mas o MVP geralmente usa uma estrutura de ligações que é o MVC abaixo. O THUS MVP está em um nível arquitetural superior ao MVC e em um padrão de wrapper acima do MVC.


Também vale lembrar que existem diferentes tipos de MVPs. Fowler dividiu o padrão em dois - Controle Passivo de Visão e Supervisão.

Ao usar o Passive View, seu modo de exibição geralmente implementa uma interface refinada com propriedades mapeadas mais ou menos diretamente para o widget subjacente da interface do usuário. Por exemplo, você pode ter um ICustomerView com propriedades como Nome e Endereço.

Sua implementação pode ser algo como isto:

public class CustomerView : ICustomerView
{
    public string Name
    { 
        get { return txtName.Text; }
        set { txtName.Text = value; }
    }
}

Sua turma do Presenter conversará com o modelo e o "mapeará" para a visualização. Essa abordagem é chamada de "Visão Passiva". O benefício é que a visualização é fácil de testar e é mais fácil alternar entre plataformas de interface do usuário (Web, Windows / XAML etc.). A desvantagem é que você não pode alavancar coisas como ligação de dados (o que é realmente poderoso em estruturas como WPF e Silverlight ).

O segundo sabor do MVP é o Controlador de Supervisão. Nesse caso, o seu View pode ter uma propriedade chamada Customer, que novamente é vinculada aos widgets da interface do usuário. Você não precisa pensar em sincronizar e gerenciar minuciosamente a visualização, e o Controlador de supervisão pode intervir e ajudar quando necessário, por exemplo, com lógica de interação completa.

O terceiro "sabor" do MVP (ou alguém poderia chamar isso de padrão separado) é o Modelo de Apresentação (ou algumas vezes chamado de Model-View-ViewModel). Comparado ao MVP, você "mescla" o M e o P em uma classe. Você tem seu objeto de cliente ao qual seus widgets da interface do usuário estão vinculados a dados, mas também possui campos específicos da interface do usuário, como "IsButtonEnabled" ou "IsReadOnly" etc.

Acho que o melhor recurso que encontrei para a arquitetura da interface do usuário é a série de postagens de blog feitas por Jeremy Miller no The Build Your Own CAB Series Table of Contents . Ele cobriu todos os tipos de MVP e mostrou o código C # para implementá-los.

Também escrevi no blog sobre o padrão Model-View-ViewModel no contexto do Silverlight no YouCard. Visite novamente: Implementando o padrão ViewModel .


MVC (Model View Controller)

A entrada é direcionada primeiro ao Controlador, não à visualização. Essa entrada pode ser proveniente de um usuário interagindo com uma página, mas também pode ser simplesmente inserindo um URL específico em um navegador. Em qualquer um dos casos, é um Controlador com interface para iniciar algumas funcionalidades. Há um relacionamento muitos-para-um entre o Controller e a View. Isso ocorre porque um único controlador pode selecionar diferentes visualizações a serem renderizadas com base na operação que está sendo executada. Observe a seta de sentido único de Controller para View. Isso ocorre porque o View não tem nenhum conhecimento ou referência ao controlador. O Controller repassa o Modelo, para que haja conhecimento entre a Visualização e o Modelo esperado que está sendo passado para ele, mas não o Controlador que o serve.

MVP (Model View Presenter)

A entrada começa com a exibição, não o apresentador. Há um mapeamento individual entre a View e o Presenter associado. A exibição contém uma referência ao apresentador. O Apresentador também está reagindo aos eventos que estão sendo acionados a partir da Visualização, para que esteja ciente da Visualização à qual está associado. O Presenter atualiza a Visualização com base nas ações solicitadas que ele executa no Modelo, mas a Visualização não reconhece o Modelo.

Para mais Reference


Model-View-Controller

MVC é um padrão para a arquitetura de um aplicativo de software. Separa a lógica do aplicativo em três partes separadas, promovendo a modularidade e a facilidade de colaboração e reutilização. Ele também torna os aplicativos mais flexíveis e acolhedores para as iterações. Ele separa um aplicativo nos seguintes componentes:

  • Modelos para manipulação de dados e lógica de negócios
  • Controladores para lidar com a interface do usuário e o aplicativo
  • Visualizações para manipulação de objetos e apresentações da interface gráfica do usuário

Para deixar isso um pouco mais claro, vamos imaginar um aplicativo simples de lista de compras. Tudo o que queremos é uma lista do nome, quantidade e preço de cada item que precisamos comprar esta semana. Abaixo, descreveremos como podemos implementar algumas dessas funcionalidades usando o MVC.

Model-View-Presenter

  • O modelo são os dados que serão exibidos na visualização (interface com o usuário).
  • A exibição é uma interface que exibe dados (o modelo) e roteia comandos do usuário (eventos) para o Presenter para atuar com base nesses dados. A visualização geralmente tem uma referência ao seu Apresentador.
  • O apresentador é o "intermediário" (interpretado pelo controlador no MVC) e tem referências a ambos, visualização e modelo. Observe que a palavra "Modelo" é enganosa. Deveria ser a lógica de negócios que recupera ou manipula um modelo . Por exemplo: se você tiver um usuário armazenando um banco de dados em uma tabela do banco de dados e o seu View desejar exibir uma lista de usuários, o Presenter terá uma referência à lógica comercial do banco de dados (como um DAO) de onde o Presenter consultará uma lista de usuários.

Se você quiser ver uma amostra com implementação simples, verifique this post no GitHub

Um fluxo de trabalho concreto de consulta e exibição de uma lista de usuários de um banco de dados poderia funcionar assim:

Qual é a diferença entre os padrões MVC e MVP ?

Padrão MVC

  • Controladores são baseados em comportamentos e podem ser compartilhados entre visualizações

  • Pode ser responsável por determinar qual visualização exibir (Front Controller Pattern)

Padrão MVP

  • A vista é mais fracamente acoplada ao modelo. O apresentador é responsável por vincular o modelo à visualização.

  • Teste de unidade mais fácil porque a interação com a visualização é feita através de uma interface

  • Geralmente, visualize o mapa do apresentador um a um. Visualizações complexas podem ter vários apresentadores.


A resposta mais simples é como a visualização interage com o modelo. No MVP, a visualização é vinculada ao apresentador, que atua como intermediário entre a visualização e o modelo, recebendo informações da visualização, obtendo dados do modelo, executando uma lógica de negócios e, finalmente, atualizando a visualização. No MVC, o modelo atualiza a visualização diretamente, em vez de voltar pelo controlador.


this belo vídeo do tio Bob, onde ele explica brevemente o MVC e o MVP no final.

IMO, MVP é uma versão aprimorada do MVC, onde você basicamente separa a preocupação do que você vai mostrar (os dados) de como você vai mostrar (a exibição). O Presenter inclui um pouco da lógica comercial da sua interface do usuário, impõe implicitamente quais dados devem ser apresentados e fornece uma lista de modelos de exibição idiota. E quando chega a hora de mostrar os dados, você simplesmente conecta sua visualização (provavelmente inclui os mesmos IDs) ao seu adaptador e define os campos de visualização relevantes usando esses modelos de visualização com uma quantidade mínima de código sendo introduzida (apenas usando setters). Seu principal benefício é que você pode testar sua lógica de negócios da interface do usuário em várias / várias visualizações, como mostrar itens em uma lista horizontal ou vertical.

No MVC, falamos através de interfaces (limites) para colar diferentes camadas. O controlador é um plug-in para nossa arquitetura, mas não tem essa restrição para impor o que mostrar. Nesse sentido, o MVP é uma espécie de MVC com um conceito de visualizações conectável ao controlador através de adaptadores.

Espero que isso ajude melhor.


Minha humilde visão curta: MVP é para grandes escalas e MVC para pequenas escalas. Com o MVC, às vezes sinto que o V e o C podem ser vistos como dois lados de um único componente indivisível, diretamente vinculado a M, e inevitavelmente cai para isso ao descer para escalas mais curtas, como controles de interface do usuário e widgets de base. Nesse nível de granularidade, o MVP faz pouco sentido. Quando alguém, pelo contrário, vai para escalas maiores, a interface adequada se torna mais importante, o mesmo com a atribuição inequívoca de responsabilidades, e aqui vem o MVP.

Por outro lado, essa regra de escala de um polegar pode pesar muito pouco quando as características da plataforma favorecem algum tipo de relação entre os componentes, como com a web, onde parece ser mais fácil implementar o MVC do que o MVP.


Você esqueceu o ADR ( Action-Domain-Responder ).ADR

Conforme explicado em alguns gráficos acima, há uma relação / link direto entre o modelo e a visualização no MVC. Uma ação é executada no Controlador , que executará uma ação no Modelo . Essa ação no modelo , vai desencadear uma reação na exibição . A exibição é sempre atualizada quando o estado do modelo é alterado.

Algumas pessoas continuam esquecendo que o MVC foi criado no final dos anos 70 " e que a Web foi criada apenas no final dos anos 80" / início dos 90 ". O MVC não foi criado originalmente para a Web, mas para aplicativos de área de trabalho, onde o controlador , Model e View coexistiriam juntos.

Como usamos estruturas da Web ( por exemplo: Laravel ) que ainda usam as mesmas convenções de nomenclatura ( model-view-controller ), tendemos a pensar que deve ser o MVC, mas na verdade é outra coisa.

Em vez disso, dê uma olhada no ADR . No ADR, o Controlador obtém uma Ação , que executará uma operação no Modelo / Domínio . Até agora, o mesmo. A diferença é que, em seguida, ele coleta a resposta / dados dessa operação e os passa para um Respondente ( por exemplo :.view() ) para renderização. Quando uma nova ação é solicitada no mesmo componente, o Controlador é chamado novamente e o ciclo se repete. No ADR, não há conexão entre o Modelo / Domínio e a Visualização ( resposta do Reponser ).

Nota: A Wikipedia afirma que " cada ação de ADR, no entanto, é representada por classes ou fechamentos separados ". Isto não é necessariamente verdade. Várias ações podem estar no mesmo controlador e o padrão ainda é o mesmo.

mvc adr model-view-controller action-domain-responder


  • MVP = Model-View-Presenter
  • MVC = Model-View-Controller

    1. Ambos os padrões de apresentação. Eles separam as dependências entre um Modelo (pense em objetos de Domínio), sua tela / página da Web (a Visualização) e como sua UI deve se comportar (Apresentador / Controlador)
    2. Eles são bastante similares em conceito; as pessoas inicializam o Apresentador / Controlador de maneira diferente, dependendo do gosto.
    3. Um ótimo artigo sobre as diferenças está here . O mais notável é que o padrão MVC tem o Model atualizando a View.






glossary