Padrão de design MVPVM

O padrão de design Model-View-Presenter-ViewModel para WPF

Bill Kratochvil

Baixar o código de exemplo

De todos os projetos bem-sucedidos de que participei, os de maior sucesso compartilharam um resultado comum: à medida que o aplicativo crescia em tamanho, a base de código diminuía. À primeira vista, isso pode parecer contraditório, mas codificar em um ambiente Agile nos leva a uma base de código reduzida. À medida que requisitos são alterados, ocorre a refatoração, e essa oportunidade de refatoração, aliada a uma visão retrospectiva, oferece a capacidade de reutilizar componentes existentes de maneira mais eficiente e, ao mesmo tempo, de eliminar código duplicado no processo.

Por outro lado, houve alguns projetos monolíticos, algumas vezes considerados bem-sucedidos, onde o código-fonte crescia sem limite, com pouca oportunidade para reutilização. Esses projetos passaram a demandar muitos recursos e tornaram-se um risco ao crescimento futuro. Qual a diferença fundamental entre eles? O padrão de design básico usado. Os padrões que você usar irão determinar se você vai ficar de mãos atadas ou se vai manter-se aberto às oportunidades que o futuro pode vir a oferecer.

Neste artigo, vou apresentar um desses padrões — esquecido por muitos desenvolvedores do Windows Presentation Foundation (WPF), devido à popularidade do padrão Model-View-ViewModel (MVVM) — chamado padrão Model-View-Presenter-ViewModel (MVPVM). Esse padrão de design de aplicativo empresarial foi introduzido ao projeto Prism de padrões e práticas da Microsoft (Prism.CodePlex.com). (Observação: esse padrão não foi nomeado, de modo que eu me refiro a ele como MVPVM.) O Prism é mais bem descrito por um trecho de sua visão geral em seu site:

"O Prism fornece orientações criadas para ajudá-lo a mais facilmente fazer o design e criar aplicativos avançados, flexíveis e de fácil manutenção para área de trabalho do Windows Presentation Foundation (WPF), aplicativos Silverlight para Internet (RIAs) e aplicativos para Windows Phone 7. Usando padrões de design que incorporam importantes princípios arquitetônicos de design como separação de preocupações e menor rigidez, o Prism ajuda-o a projetar e criar aplicativos usando componentes menos rígidos que podem evoluir de maneira independente mas podem ser integrados de maneira fácil e direta ao aplicativo global. Esses tipos de aplicativos são conhecidos como aplicativos compostos."

A popularidade e o sucesso do MVVM suplanta o MVPVM, mesmo sendo o MVPVM uma evolução do MVVM (como este artigo irá demonstrar). O MVPVM fornece toda a potência e recursos do MVVM ao mesmo tempo em que introduz escalabilidade e extensibilidade do padrão Model-View-Presenter (MVP). Se você acredita que o MVVM evoluiu a partir do MVP para WPF, então você vai achar este artigo esclarecedor.

Antes que possamos reconhecer a potência e os benefícios do MVPVM, precisamos entender como esse padrão evoluiu. Precisamos entender nossa história. O padrão Model-View-Controller (MVC) é um componente crucial para atingirmos esse entendimento, de modo que vou antes apresentar o MVC, talvez de uma maneira nunca antes vista por você.

O padrão MVC

Observe que essa discussão sobre o MVC se dá no contexto de aplicativos de área de trabalho; aplicativos da Web são outra história e vão além do escopo desse artigo.

No documento “GUI Architectures” de Martin Fowler (bit.ly/11OH7Y), ele afirma o seguinte sobre o MVC: “Pessoas diferentes, lendo sobre o MVC em lugares diferentes fazem ideias diferentes sobre ele e as descrevem como ‘MVC'. Como se isso já não causasse bastante confusão, você ainda sofre o efeito de mal-entendidos sobre o MVC que se propagam através de várias deturpações." O documento “Whatsa Controller Anyway” em bit.ly/7ajVeS resume muito bem esse ponto, afirmando: "Profissionais de informática em geral têm uma tendência incômoda de sobrecarregar termos. Isso quer dizer que eles tendem a atribuir mais de um significado (algumas vezes contraditórios) à mesma palavra." 

O MVC do Smalltalk fica ainda mais complicado pelo fato de que aos desenvolvedores falta uma experiência fundamental, comum a seus excelentes arquitetos, em relação ao ambiente do arquiteto. Assim, a sobrecarga de termos e as deturpações se complicam ainda mais pelo fato que a maioria de nós não sabe nem o que é um controlador, porque nunca precisamos usar um. O sistema operacional sempre cuidou dessa funcionalidade para nós. Com alguns fatos que nos forneçam a experiência fundamental comum que nos falta, você vai descobrir que o MVC é fácil de compreender e que o "C" do MVC não tem nada a ver com o "P" do MVP.

O controlador tem de fato uma origem concreta (que vale a pena entender, mas não necessariamente corresponde a abordagens modernas ao MVC no contexto das atuais tecnologias). O criador e pai do MVC, Trygve Reenskaug, escreveu sobre isso em 1979 em seu documento sobre “Models-Views-Controllers” (bit.ly/2cdqiu). Esse documento começa por apresentar alguma ideia sobre o objetivo do controlador. Reenskaug escreveu:

"Um controlador é o vínculo entre um usuário e o sistema. Ele fornece entradas ao usuário providenciando exibições relevantes que se apresentam em locais adequados na tela. Ele fornece meios à saída do usuário apresentando ao usuário menus ou outros meios para atribuição de comandos e dados. O controlador recebe as saídas do usuário, as traduz para mensagens adequadas e as transmite para uma ou mais exibições.

Um controlador nunca deve complementar as exibições. Por exemplo, ele nunca deve conectar as exibições de nós desenhando setas entre eles.

Por outro lado, uma exibição nunca deve reconhecer entradas do usuário, tais como operações de mouse e pressionamento de teclas. Deveria ser sempre possível gravar um método em um controlador que envie mensagens às exibições, as quais reproduzam fielmente qualquer sequência de comandos do usuário.

O conceito é ilustrado na Figura 1.

Uma "mensagem", no contexto de programação MVC orientada a objeto (OOP), é um meio de execução de métodos. Elas foram descritas como "mensagens" porque, naquela época, chamadas virtuais eram um conceito novo e essa era uma maneira de distingui-las de chamadas de funções estáticas. No capítulo 1.2 do livro “Smalltalk, an Introduction to Application Development Using VisualWorks” (Prentice Hall, 1995), de Trevor Hopkins e Bernard Horan, os autores observam "... se o objeto receptor compreende a mensagem que lhe foi enviada, então uma de suas operações internas (ou métodos) será executada. Isso, por sua vez, pode fazer com que ocorra algum tipo de computação (pela atuação em uma ou mais das variáveis internas do objeto)." (Observação: esse conceito OOP de "envio de mensagem" está disponível no Prism via seu EventAggregator.)

O livro descreve muito bem as responsabilidades do MVC do Smalltalk em seu capítulo 29 sobre a introdução a modelos, exibições e controladores, ensinando-nos que controladores derivam da classe Controller. Ele afirma que "instâncias dessa classe referem-se a um sensor que representa o mouse e o teclado, de modo a poder processar a entrada". Ele continua nos dizendo que duas ações distintas iniciadas a partir de um controlador são as comunicações com o modelo (consulte a Figura 1) e as comunicações com a exibição, que não afetam o modelo.

Controller Receives Input and Sends Message (Method to Execute); Views Can’t Catch User Input
Figura 1 O controlador recebe entrada e envia mensagem (método para execução); exibições não conseguem capturar a entrada do usuário

No MVC do Smalltalk, "todas" as exibições terão um controlador e somente um controlador poderá estar ativo em um determinado instante. No MVC do Smalltalk original, a interface do usuário foi sondada; a classe ControlManager de nível superior pergunta a cada um dos controladores da exibição ativa se desejam controle. Somente a exibição que contém o cursor pode aceitar controle. Se uma exibição for de somente leitura, há uma classe NoController disponível, que é projetada para rejeitar o controle. Uma exibição com subexibições é responsável por sondar os controladores de suas subexibições. Assim que o controlador aceita o controle, ele consulta os resultados do teclado ou do mouse e envia mensagens à exibição ou ao modelo, conforme aplicável, tais como a movimentação do mouse, o clique em um botão e assim por diante. Em termos de MVVM, isso seria comparável à inscrição a eventos de controle no code-behind da exibição ou via um comando ViewModel. Quando um usuário interage com o controle, o método aplicável será chamado.

A essa altura, você pode começar a ter uma ideia do objetivo do controlador no contexto do MVC e de um ambiente que não lida automaticamente com os eventos para você. Ao contrário dos desenvolvedores de MVC do Smalltalk, desenvolvedores de WPF não precisam consultar buffers de teclado nem empacotar e criar eventos. Você simplesmente se inscreve a eles e o método aplicável irá "automaticamente" recebê-los via o padrão de evento da Microsoft. Com isso em mente, o que se segue terá, talvez, um significado diferente e menos confuso.

No artigo de Steve Burbeck, “Applications Programming in Smalltalk-80: How to Use Model-View-Controller (MVC)” (bit.ly/3ZfFCX), ele afirma o seguinte:

"O controlador interpreta as entradas de mouse e de teclado do usuário, comandando a alteração do modelo e/ou da exibição, conforme for apropriado. Por fim, o modelo gerencia o comportamento e os dados do domínio do aplicativo, responde às solicitações de informação sobre seu estado (em geral, vindo da exibição) e responde a instruções para mudar de estado (em geral, vindo do controlador)."

Consulte a Figura 2 para obter uma ilustração desse conceito.

Smalltalk Model-View-Controller
Figura 2 Model-View-Controller do Smalltalk

Um último ponto que pode esclarecer sobre o que poderia vir a ser um tópico nebuloso encontra-se no documento, “Twisting the Triad, the Evolution of the Dolphin Smalltalk MVP Application Framework”, por Andy Bower e Blair McGlashan em bit.ly/o8tDTQ (baixe o PDF). Esse é um dos mais abrangentes documentos que já li sobre o assunto. Os autores fazem as seguintes observações sobre o controlador: "As exibições, é claro, são responsáveis pela exibição dos dados de domínio enquanto os controladores lidam com os gestos brutos do usuário que irão, por fim, desempenhar ações sobre esses dados."  

Eu chamo atenção para esse ponto para ter uma oportunidade de fornecer outra definição. Para entender completamente o artigo (e outros, sobre o MVC), você deve entender o que significa "gestos" (consulte a Figura 1). Em minha pesquisa, deparei-me com o artigo “An Introduction to GUI Programming with UIL and Motif” (bit.ly/pkzmgc), que relata o seguinte:

"A essência dessas etapas é que um programa Motif não faz nada até que o usuário solicite alguma ação. As ações são solicitadas pela seleção de um item de menu, pelo clique em um botão ou em outra janela ou pressionando uma tecla. Esses são, em conjunto, gestos de usuário. Cada gesto irá disparar uma função de aplicativo para executar alguma tarefa."

Andy Bower, coautor de “Torcendo a tríade", compartilhou comigo suas ideias sobre "gestos":

"Minha opinião sobre 'gestos' é que eles são a aglutinação de um ou mais eventos de usuário formando algo mais significativo.

Por exemplo, um TextController pode absorver eventos de tecla pressionada e de tecla retornando e convertê-los em gestos individuais de 'tecla acionada'. Do mesmo modo, um SelectionInListController (o controlador anexado a uma caixa de listagem) pode absorver vários eventos de mouse para baixo, acompanhamento de mouse e mouse para cima em uma lista e tratá-los como um único gesto de 'seleção' na lista.

Olhando dessa maneira, vemos que um sistema operacional moderno e orientado por eventos já executa a maior parte desse processamento de gestos para nós.

Resumindo a lógica do controlador, pode-se notar que a função do controlador é bem consistente entre as variações referenciadas do MVC. Como controladores da Microsoft (widgets) manipulam "as entradas de mouse e de teclado do usuário", você simplesmente inscreve-se nos eventos e indica o método que precisa ser executado — o "controlador" em seus controles inteligentes executa o método para você (manipulado no nível do sistema operacional). Assim, você não precisa de um controlador, como já foi claramente indicado pelo artigo “Twisting the Triad”. Sem o controlador, você fica apenas com o padrão Model-View para aplicativos do Windows. Você precisa ter isso em mente ao estudar o MVC e seus modelos de aplicativo e de apresentação, porque sem o controlador não haverá uma tríade (consulte a Figura 3).

Without the Controller, It Has Been Model-View (not Model-View-Controller)
Figura 3 Sem o controlador, ele se torna Model-View (e não Model-View-Controller)

Vale mencionar que não foi somente o controlador que causou ambiguidade com o MVC. Com o MVC do Smalltalk, a lógica empresa/domínio está no modelo e com o MVC do VisualWorks o ApplicationModel contém a lógica do "aplicativo" necessária para apresentar um ou mais objetos empresa/domínio ao usuário (consulte a Figura 4). O artigo “Twisting the Triad” aborda isso com mais detalhes. Se você considerar que o Application Model e o Presentation Model têm a mesma funcionalidade, sendo a nítida diferença que o Presentation Model "não consegue" acessar a visualização (Martin Fowler fez uma clara diferença de maneira a não sobrecarregar os termos), então desenvolvedores de WPF podem rapidamente entender o Presentation Model porque, essencialmente, ele é o MVVM. John Gossman, fundador e pai do MVVM, explica isso em sua entrada no blog “PresentationModel and WPF” em bit.ly/pFs6cV. Assim como Martin, ele fez questão de não sobrecarregar os termos. Isso nos dá, de maneira efetiva, uma clara compreensão do que é o MVVM; ele é uma "versão específica para o WPF do padrão PresentationModel"

VisualWorks Model-View-Controller
Figura 4 Model-View-Controller do VisualWorks

Observar o MVC em sua verdadeira dimensão irá ajudá-lo a entender as verdadeiras funções do modelo e da exibição. Esses são, em essência, os dois únicos locais para a lógica empresarial/domínio. Após ler “Twisting the Triad”, você irá observar que foram as responsabilidades do Application Model que foram transferidas ao apresentador e que você não pode simplesmente substituir o controlador por um apresentador — não faria sentido, porque eles não são sinônimos.

O padrão MVP

Vai além do escopo deste artigo anilar o MVP com a atenção merecida; felizmente, há vários documentos que o abordam, como “Twisting the Triad” e o “Potel Paper", que você pode baixar em bit.ly/dF4gNn (PDF).

Eu vou, no entanto, observar que o artigo "Twisting the Triad" menciona um ponto importante ao qual eu aludi, que levou à evolução do MVC para o MVP:

"Outro recurso irritante do MVC, pelo menos em relação ao Dolphin, era a ideia de que um controlador não se ajusta de maneira harmoniosa ao ambiente Windows. O Microsoft Windows, como a maioria dos sistemas operacionais gráficos, fornece um conjunto de widgets nativos a partir dos quais podem ser construídas interfaces de usuário. Essas 'janelas' já incluem a maior parte da funcionalidade de controlador incorporada como parte do controle subjacente do sistema operacional."

Eu gostaria também de enfatizar, do artigo “GUI Architectures” de Martin Fowler sua declaração que "Essa necessidade de manipular os widgets diretamente foi vista por muitos como uma solução alternativa pobre e ajudou no desenvolvimento da abordagem Model-View-Presenter". É importante entender isso porque o MVVM incutiu a mentalidade do Presentation Model em vários desenvolvedores de WPF; eles acreditam que atualizar a exibição diretamente seja uma forma de "programação pobre". Isso é verdade para o MVVM e o Presentation Model porque assim que você se referenciar à exibição, não será mais possível reutilizar o ViewModel com uma exibição diferente (a principal razão de ser dessa regra). Esse fator limitante foi uma das razões pela qual o MVC do Smalltalk evoluiu para o padrão MVP. Com o MVPVM, os desenvolvedores podem acessar diretamente a exibição e o ViewModel (rigidamente acoplados), o que permite à exibição e ao ViewModel permanecerem completamente desacoplados (consulte a Figura 5). As exibições podem reutilizar diferentes ViewModels, e os ViewModels podem ser reutilizados por diferentes exibições (como você verá mais tarde, quando eu abordar o padrão MVPVM); esse é um dos grandes benefícios do MVPVM.

Model-View-Presenter, Supervising Controller
Figura 5 Model-View-Presenter, Supervising Controller

Andy Bower compartilhou comigo a seguinte informação sobre o tópico, a fim de melhor esclarecer:

"Talvez valha a pena destacar que o objetivo de todos esses padrões é a reutilização através da conectividade. Manter o acoplamento menos rígido sempre que possível e as interfaces tão pequenas quanto possível oferece o máximo de reutilização na maneira como os componentes podem ser combinados.

Entretanto, observe que o modelo tem, efetivamente, duas interfaces que devem ser compatíveis com qualquer exibição e apresentador associado. A primeira é a interface padrão de função de chamada, usada para capturar/definir valores e executar comandos. A segunda é a interface event, que deve ser a mesma que é esperada pela exibição (padrão observador). Essa combinação de interfaces podem ser chamadas de 'protocolo'.

Por exemplo, no MVP do Dolphin, um widget de lista (triad) precisa de três componentes com protocolos compatíveis. Um ListModel, um ListView e um ListPresenter.”

Uma vez que você entenda porque não deve atualizar uma exibição diretamente — e percebe que essa razão o permitiria reutilizar com eficiência objetos, eliminando a restrição de impossibilidade de atualizar a exibição — você terá a opção de adotar as novas oportunidades que a evolução oferece. Você vive em um mundo ágil e, assim como seu código, você precisa mudar seus padrões de pensamento "para que a história não se repita".

O padrão MVPVM

Aprendi esse padrão no início do ciclo de vida do Prism, especificamente no Drop 7 do CompositeWPF. Perdido em meio a todos os místicos poderes do Prism, eu reconheci o padrão MVP, que me ajudou a me situar. Eu aprendi rapidamente (como ensino a novos desenvolvedores) a simplesmente ir ao apresentador e nele obter o ponto de partida para decifrar o código e o aplicativo. Como a execução do código chega lá pode ser aprendido mais tarde e não precisa interferir com cronogramas rígidos; o impacto das curvas de aprendizado difíceis pode ser gerenciado.

As seguintes definições dos componentes do MVPVM contém trechos de “Twisting the Triad” conforme aplicáveis; eu considero essa informação muito esclarecedora, abrangente e precisa, de modo que, no interesse de fornecer a você a melhor informação possível, eu simplesmente vou citar as definições desse artigo. Essas definições continuam válidas hoje para o MVPVM (consulte a Figura 6) assim como eram válidas para o MVP em março de 2000 quando “Twisting the Triad” foi escrito.

Model-View-Presenter-ViewModel
Figura 6 Model-View-Presenter-ViewModel

(Observação: Prism é o contexto deste artigo, no entanto, o MVPVM funciona sem o Prism; os vários componentes estarão simplesmente acoplados rigidamente a suas implementações, em vez de serem resolvidos — acoplados de maneira menos rígida pelo Unity ou pelo contêiner de injeção de dependência do Managed Extensibility Framework [MEF].)

MVPVM: o modelo

"Esses são os dados sobre os quais a interface de usuário irá operar. Ele é, geralmente, um objeto de domínio e a intenção é que tais objetos não devam reconhecer a interface de usuário." —“Twisting the Triad”

A separação do modelo do ViewModel é necessária para abordar as preocupações de injeção de dependência e seu uso na camada de lógica comercial (BLL) e na camada de acesso a dados (DAL) para criar, ler, atualizar, excluir e listar (CRUDL) dados persistentes. No MVPVM, somente o DAL tem acesso aos objetos Model persistentes.

MVPVM: A exibição

"O comportamento de uma exibição no MVP é muito próximo àquele no MVC. É responsabilidade da exibição exibir o conteúdo de um modelo. É esperado que o modelo dispare notificações adequadas de alteração sempre que seus dados sejam modificados e permitam que a exibição 'se destaque' do modelo seguindo o padrão Observer. De maneira análoga ao MVC, isso permite que várias exibições sejam conectadas a um único modelo. —“Twisting the Triad”

(Observação: Eu usei a citação anterior para enfatizar que o MVP não é um padrão novo e que ele é tão válido hoje como era válido quando o MVP evoluiu a partir do MVC. Entretanto, a citação refere-se a "Model", enquanto o MVPVM emprega o “ViewModel.”)  

Com o MVPVM, nunca há a necessidade de se ter um código no code-behind. O apresentador tem acesso à exibição e pode se inscrever a eventos, manipular controles e manipular a interface de usuário conforme necessário. Isso mostrou ser uma vantagem durante o desenvolvimento do aplicativo multiplataforma que acompanha esse artigo. A ListBox de usuário não respeitava a ligação de dados para o evento alterado pela seleção, de modo que eu precisei desenvolver um modo que funcionasse para todas as três plataformas (porque elas compartilham o mesmo código). Quando a exibição é ativada, eu chamo a WireUpUserListBox (consulte a Figura 7, linha 174) e uso a exibição para obter uma referência para meu controle lstUserList (que reside em um DataTemplate). Uma vez encontrado, eu conecto ao evento SelectionChanged e atualizo a propriedade SelectedUser do ViewModel. Isso funciona para área de trabalho, Silverlight e Windows Phone.

Benefits of Being Able to Access the View Directly
Figura 7 Benefícios da capacidade de acessar diretamente a exibição

Uma exibição não reconhece o ViewModel, de modo que eles não são rigidamente acoplados. Desde que um ViewModel suporte todas as propriedades às quais a exibição estiver associada, ele poderá facilmente usar a exibição. O apresentador é responsável por conectar exibições a seus ViewModels, configurando seus DataContext ao ViewModel aplicável.

MVPVM: O apresentador

"Enquanto é responsabilidade da exibição exibir dados de modelo, é o apresentador que controla a maneira como o modelo pode ser manipulado e alterado pela interface de usuário. É aí que reside a essência do comportamento de um aplicativo. Em muitos aspectos, o apresentador do MVP é equivalente ao modelo de aplicativo no MVC; a maior parte do código que lida com a maneira pela qual a interface funciona está incorporada a uma classe de apresentador. A principal diferença é que um apresentador é ligado diretamente à sua exibição de modo que os dois possam colaborar intimamente em suas funções de fornecimento da interface de usuário a um modelo específico." —“Twisting the Triad”

O apresentador terá dependências das interfaces para as BLLs das quais ele precisa recuperar objetos de domínio (dados), como mostra o painel esquerdo da Figura 8. Ele usará as instâncias resolvidas como configuradas no módulo (consulte a Figura 8, painel inferior direito) ou bootstrapper para acessar os dados e preencher o ViewModel.

Security Module Code
Figura 8 Código de módulo de segurança

Normalmente, somente o apresentador será acoplado rigidamente a componentes MVPVM. Ele será rigidamente acoplado à exibição, ao ViewModel e às interfaces BLL. Apresentadores não se destinam a serem reutilizados; eles abordam determinadas preocupações assim como as lógicas/regras de negócios para aquelas preocupações. Nos casos em que o apresentador pode ser reutilizado em diversos aplicativos corporativos, provavelmente um módulo seria mais adequado para a tarefa — isto é, você poderia criar um módulo de logon (projeto) que poderia ser reutilizado por todas os seus aplicativos corporativos. Se você escrever seu código para uma interface, o módulo poderá facilmente ser reutilizado usando tecnologias de injeção de dependência como MEF ou Unity.

MVPVM: O ViewModel

"No MVP, o modelo é simplesmente um objeto de domínio e não qualquer expectativa de (ou um link para) uma interface de usuário." —“Twisting the Triad”

Isso impede que o ViewModel seja rigidamente acoplado a uma única exibição, permitindo sua reutilização por várias exibições. Da mesma forma, o ViewModel não terá lógica de negócios para aplicativo, de modo que ViewModels possam ser facilmente compartilhados entre aplicativos empresariais. Isso promove a reutilização e a integração de aplicativos. Por exemplo, observe na Figura 8, painel superior direito, linha 28. Esse SecurityCommandViewModel reside no projeto Gwn.Library.MvpVm.xxxx (onde xxxx = Silverlight, área de trabalho ou Windows Phone). Porque um User ViewModel será necessário na maioria dos aplicativos, esse será um componente reutilizável. Eu preciso me cuidar para não o poluir com lógica de negócios específicas do aplicativo de demonstração. Isso não é um problema para o MVPVM, porque a lógica de negócios será manipulada pelo apresentador e não dentro do ViewModel (consulte a Figura 6).

(Observação: À medida que as propriedades do ViewModel são preenchidas pelo apresentador, elas irão gerar eventos NotifyPropertyChanged, que alertarão a exibição quanto à existência de novos dados — é responsabilidade da exibição atualizar-se em relação aos dados do ViewModel mediante a notificação.

A camada de lógica comercial

As BLLs não reconhecem os dados que permanecem no modelo. Elas operam exclusivamente com objetos de domínio e interfaces. Normalmente, você irá usar uma injeção de dependência para resolver sua interface DAL na BLL, de modo que você possa, mais tarde, alternar a DAL sem afetar qualquer código downstream. Observe na Figura 9, linha 34, que eu estou usando uma implementação MockBll para IBusinessLogicLayer para meu aplicativo de demonstração. Posteriormente, eu poderei facilmente substituí-la por uma implementação de produção da interface com uma linha de código, pois eu a desenvolvi para uma interface.

Registering BLL, DAL and Commands
Figura 9 Registrando BLL, DAL e Commands

A lógica de negócios não se limita às BLLs. Na Figura 9, eu registro tipos nomeados (para IPresenterCommand) de modo a poder usar injeção de dependência como um alocador. Quando um usuário clica em um botão (linhas 29 a 33 na Figura 10), o parâmetro de comando é resolvido (instanciado) pela baseclass e o comando aplicável é executado. Por exemplo, o LoginCommand (Figura 8, painel superior direito) é um comando que irá ativar o UserManagerView. Tudo que foi necessário para a conexão foi um comando Button em XAML e uma entrada em SecurityModule (consulte a Figura 8, painel inferior direito, linha 32).

DataTemplate for the UserCommandViewModel
Figura 10 DataTemplate para o UserCommandViewModel

A camada de acesso a dados

Dados de domínio persistentes poderiam ser armazenados em banco de dados SQL ou em arquivos XML ou de texto, ou recuperados de um serviço REST. Com o MVPVM, somente a DAL retém informação específica necessária para recuperação de dados. A DAL irá retornar somente objetos de domínio para a BLL. Isso dispensa a necessidade de a BLL reconhecer cadeias de caracteres de conexão, manipulações de arquivo, serviços REST e assim por diante. Isso aprimora e escalabilidade e extensibilidade; você pode facilmente alternar sua DAL de um arquivo XML para um serviço em nuvem sem afetar qualquer código existente fora da DAL e do arquivo de configuração do aplicativo. Desde que seus testes de unidade de sua nova DAL funcionem para os processos CRUDL, você pode configurar o aplicativo para usar a nova DAL sem impactar aplicativos atuais e suas utilizações.

Entendendo o histórico, beneficiando-se da experiência

Graças à equipe de padrões e práticas, consegui que meus clientes tivessem sucesso ao usar, sem falhas, tecnologias muito novas e de alto risco e padrões como o MVPVM. Descobri, ao acompanhar a evolução do time, das tecnologias e dos padrões, que à medida que surgem novas tecnologias e padrões, posso trazer do passado experiência que ajude a me orientar mais facilmente nesse novo território.

MVP é um padrão constante e consistente que vi sendo usado desde o início de meus estudos de arquitetura usando projetos de padrões e práticas. Para compreender completamente o MVP, você deve entender o seu histórico, em especial os componentes do MVC. Isso não é fácil, por causa dos vários fatores discutidos.

Mas compreendendo nosso passado e as razões de nossa evolução, podemos mais rapidamente entender a necessidade e o poder de padrões mais novos. Mesmo com o Prism e toda sua complexidade e mágica, você será capaz de suplantar uma difícil curva de aprendizado, simplesmente por conhecer esse histórico e entender a necessidade por padrões mais novos. Em todos os projetos de sucesso de que participei desde o surgimento desse padrão nas primeiras versões do Prism, o MVPVM não apresentou problemas, dificuldades ou obstáculos (eles parecem ter sido eliminados durante a evolução) permitindo aos desenvolvedores aumentar a velocidade à medida que criamos aplicativos que são escaláveis, extensíveis e estáveis.

Bill Kratochvil, um prestador de serviços independente, é tecnólogo e arquiteto renomado de uma equipe de desenvolvedores de elite trabalhando em um projeto confidencial para uma empresa líder no setor médico. Sua própria empresa, a Global Webnet LLC, está sediada em Amarillo, Texas.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Andy Bower, Christina Helton e Steve Sanderson