Mostrando postagens com marcador MVC. Mostrar todas as postagens
Mostrando postagens com marcador MVC. Mostrar todas as postagens

quarta-feira, 16 de dezembro de 2009

MVC x MVP: Resumo

No artigo Considerações Históricas sobre o padrão MVC, tradução de "MVC (Model View Controller) Design Pattern", você encontra uma série de 4 posts explicando as origens do MVC e suas variações, mostrando também como as interações entre Modelo, View e Controller são reorganizadas dando origem ao padrão MVP. Em resumo:

O MVC surgiu no início dos anos 80 e inspirou muitas frameworks na época. Cada elemento na tela possuia dois componentes: uma view, responsável pela sua exibição, e um controller, responsável por interpretar os eventos disparados pelos usuários. O controller comandava o modelo, que podia enviar notificações (indiretas) para a view poder se atualizar.

Para evitar o alto acoplamento entre o modelo e a View, surgiu o Application Model MVC, ou AM-MVC. Basicamente era uma camada intermediária, que permitia blindar melhor o modelo com relação à camada de apresentação (view e controllers).

Com o surgimento de novas tecnologias nos anos 90, o papel do controller caiu em desuso, pois os próprios widgets da view passaram a ter meios melhores de lidar com os eventos realizados pelos usuários. Além disso, em alguns casos, era conveniente o Modelo, ou o AM, poderem alterar diretamente a view, sem a necessidade de mecanismos indiretos.

Neste cenário, a IBM propôs o MVP, uma variação do MVC que seria mais adequada. Os adeptos do Smalltalk simplificaram o modelo da IBM e utilizaram no Smalltalk/Dolphin. No MVP, as responsabilidades que eram do Controller são redistribuídas entre a View e o Presenter. A View se encarrega de lidar com as entradas dos usuários, enquanto o Presenter se encarrega de interagir com o Modelo. Além disso, o Application Model do AM-MVC é substituído pelo Presenter, a quem é dado o direito de interagir diretamente com a View.

Martin Fowler catalogou o MVP na forma de dois padrões distintos:

  • Supervising Presenter: nesta forma, o presenter interpreta os eventos da View e comanda o modelo, alterando seu estado. Para atualizar sua exibição na tela de modo a refletir o novo estado do modelo, a view pode interagir diretamente com objetos do modelo, e obter os dados necessários. O modelo até pode se comunicar com a view, porém indiretamente, através de eventos, segundo o padrão Observer Synchronization.
  • Passive View: nesta forma, a view e o modelo são totalmente desacoplados, e todas as interações são realizadas por meio do Presenter. É uma abordagem que favorece o teste da aplicação, pois facilita o uso de mock views.

No novo milênio, o MVC ressurgiu com força total, quase um dogma em aplicações Web. De tão usado, seus conceitos acabaram se tornando difusos, às vezes mal interpretados, e confundidos com Arquitetura em Camadas. Leia MVC versus Camadas para entender melhor a diferença.

Uma limitação do MVC em aplicações web é a dificuldade de testar a camada de apresentação (view e controllers). O MVP parece mais adequado nestes casos, e seu uso tem sido encorajado em aplicações GWT (Google Web Toolkit).

Para concluir, a grande diferença entre MVC e MVP é a forma como o Modelo, a View e o Controller interagem, de modo a prover uma solução mais adequada, de acordo com a tecnologia utilizada e os objetivos desejados. Uma comparação mais detalhada entre o AM-MVC e o MVP/Passive view pode ser encontrada no artigo Do MVC para o MVP.

domingo, 13 de dezembro de 2009

MVC em Aplicações Web

Este post é o terceiro de uma série de traduções de artigos do blog Design Codes, que falam um pouco sobre a evolução do padrão MVC desde o final dos anos 70, até chegar aos dias de hoje, momento em que uma de suas variações - o MVP - está se popularizando, tendo inclusive sido citado como uma best practice no Google I/O 2009 para o desenvolvimento de aplicações GWT.


Clique Aqui Clique Aqui Clique Aqui


Mesmo o MVC tendo sido projetado como uma framework para aplicações desktop, há 3 décadas, ele se encaixou bem em aplicações web, as quais requerem mapeamento de URLs e/ou direcionamento de mensagens HTTP (request/response). Este artigo resume o padrão MVC usado em aplicações Web.

MVC para aplicações Desktop

O padrão MVC foi introduzido no começo dos anos 80, como um framework para aplicações desktop. À época, os widgets não tinham ainda a habilidade de processar as entradas dos usuários (cliques de mouse e digitação no teclado). O MVC introduziu a entidade Controller, para agir como uma ponte entre o usuário e a aplicação. No final dos anos 80, os widgets passaram a ter suporte nativo para processamento de entradas dos usuários, tornando obsoleto o papel do controller, e o MVC deu lugar ao MVP. Mesmo que o Presenter seja comumente citado como Controller, o autêntico controller permaneceu nas sobras até o surgimento das aplicações Web baseadas em navegadores (browsers)

Web MVC

Em aplicações Web, no lado cliente, o usuário interage com o navegador, gerando requests HTTP (sejam POST ou GET) e enviam para o servidor. O servidor processa o request (extrai os dadoa da URL ou do corpo do request), executa alguma operação do negócio, e cria a resposta (uma página HTML), a qual é enviada de volta para o cliente para ser renderizada no navegador.

Colaboração

Componentes MVC residem no servidor: o modelo guarda os dados e lida com a lógica de negócios (como sempre), a view gera a resposta (página HTML) de acordo com os dados do modelo, e o controller processa as entradas dos usuários presentes nos requests HTTP, comanda o modelo - alterando o seu estado - e cria a view apropriada para ser reenviada para o cliente e renderizada na tela.

Interação

A UI mostrada abaixo tem um único use case. O usuário clica no botão "votar". No banco de dados, a coluna que salva a quantidade de votos é incrementada, e a caixa de texto é atualizada com o valor atual do número de votos.

A modelagem MVC para esta UI terá um objeto view, para gerar o HTML mostrado acima, um objeto de modelo, para incrementar e armazenar a contagem de votos, e um controller para processar o pedido "post" iniciado quando o usuário clica no botão "votar". O controller comanda o modelo, e cria a view para a geração da resposta, retornando-a para o cliente.

Nota do tradutor: Numa aplicação web escrita em Java, tipicamente é um servlet, que interage com a camada de negócios, e em seguida delega a renderização da página a um JSP (um tipo especial de servlet). A view, neste caso, tem acesso direto aos objetos do modelo que o servlet salvar como atributos da sessão do usuário. As frameworks web atuais costumam usar uma abordagem parecida com o AM-MVC, com uma camada de aplicação, que tem a finalidade de blindar os objetos de negócio dos detalhes da view, ainda que a view tenha acesso direto a esses objetos.

Do MVC para o MVP (Model-View-Presenter)

Este post é o segundo de uma série de traduções de artigos do blog Design Codes, que falam um pouco sobre a evolução do padrão MVC desde o final dos anos 70, até chegar aos dias de hoje, momento em que uma de suas variações - o MVP - está se popularizando, tendo inclusive sido citado como uma best practice no Google I/O 2009 para o desenvolvimento de aplicações GWT.


Clique Aqui Clique Aqui Clique Aqui


Neste artigo, iremos olhar mais de perto o design pattern MVP (Model-View-Presenter) e revisar a forma na qual ele evoluiu desde seus predecessores no Smalltalk ( "MVC Clássico" e "Application Model MVC"). Espero que, depois desta revisão, sejamos capazes de distinguir o MVP do MVC e endender o porquê de a discussão MVC x MVP deixar tanta gente confusa.

Abstract

O primeiro artigo sobre MVP foi pulicado em 1996 por 'Mike Potel' e declarado como a nova geração do modelo de programação C++ e Java da IBM. Era construído com base no modelo de programação do MVC Clássico do Smalltalk, com o intuito de se adaptar melhor aos novos sistemas que foram introduzidos na época e para suportar aplicações cliente-servidor (Leia mais em Web MVC).

O Smalltalk, que duas décadas antes inspirou muitas frameworks e bibliotecas com o MVC, buscava por uma nova arquitetura para a sua próxima geração de frameworks, chamada "Dolphin Smalltalk". Eles analisaram o 'Application Model MVC' (a partir de agora referenciado, neste artigo, por AM-MVC), que era a variação mais recente do MVC, e concluiram que ele não atenderia às suas necessidades. Continuaram procurando, até descobrirem o artigo da IBM descrevendo o MVP, muito similar ao AM-MVC, mas com a guinada certa que o tornava mais adequado ao que estavam procurando. Eles o lapidaram ainda mais, e chegaram a um MVP simplificado.

O modelo MVP do Dolphin Smalltalk ainda atende bem às frameworks atuais e tem sido usado como arquitetura base para aplicações Rich-Client e Thin-Client do .Net Framework (nota do tradutor: no Google I/O 2009, o MVP foi apresentado como uma best-practice para usar com o GWT). Leia mais em Web MVP.

Em 2006, Martin Fowler renomeou o "Dolphin MVP" para Supervising Controller, dando um passo atrás em direção ao AM-MVC, e apresentou uma outra variação do MVP chamada Passive View.

Este artigo foca no MVP/Dolphin e não no MVP/IBM por dois motivos:

  • Primeiro, por ser uma tendência atual. O MVP/IBM possui raizes extras como Interactor, Command e Selection desnecessários nos dias de hoje.
  • Segundo, este artigo tenta distinguir o MVP do MVC, apresentando-os lado a lado, e explicando a forma como o MVP evoluiu a partir do MVC.

Os adeptos do Dolphin apresentam o MVP como uma evolução do AM-MVC, onde o Presenter substitui o Application Model; A IBM, por sua vez, apresenta o MVP como uma evolução do MVC Clássico, onde o Presenter substitui o Controller. De fato, o MVP/IBM é o original, mas a abordagem do Dolphin é mais atraente e fácil de explicar, uma vez que o AM-MVC é muito mais próximo do MVP do que o Controller do MVC Clássico.

O Conceito MVC

A idéia por trás do MVC é fazer uma clara separação entre os objetos do domínio (model) e os objetos da apresentação (view/controller). Ele utiliza o mecanismo Observer-Synchronization para suportar múltiplas apresentações (observadores) de um mesmo objeto de domínio (observável), e para manter os objetos de domínio completamente desacoplados dos seus respectivos objetos de apresentação.

Este conceito foi largamente experimentado nas últimas três décadas, de forma que mesmo com as significativas melhorias que o MVP introduz, no final das contas o conceito continua o mesmo.

O MVC Clássico e o 'Application Model' MVC (AM-MVC)

Antes de continuar, é interessante ler sobre os predecessores do MVP, no primeiro artigo desta série, que fala sobre o Padrão MVC. Em resumo: Tanto no 'MVC Clássico' como no 'AM-MVC', a view é um widget da tela, e cada view tem como par um controller, que processa as entradas do usuário (por exemplo cliques de mouse e digitação no teclado), e comanda o modelo conforme apropriado. O AM-MVC introduz o 'Application Model', que age como uma classe intermediária entre o modelo e a apresentação (view/controllers), de forma a proteger o modelo de detalhes da apresentação.

O que há de errado com o AM-MVC?

Os adeptos do Dolphin Smalltalk esbarraram com o fato de que o AM-MVC não seria mais aplicável, e que ele tinha alguns problemas de usabilidade.

  • Não era mais aplicável, pois não mais havia necessidade por um controller para escutar aos eventos do mouse e teclado. Isso ocorreu após sistemas operacionais como o MS Windows diponibilizassem conjuntos nativos de widgets com os quais a UI podia ser construída. Os próprios widgets capturavam os eventos de mouse e teclado, tornando o controller desnecessário.
  • O maior problema de usabilidade era que, apesar do AM ser responsável por lógica da view, ele não podia acessá-la diretamente: Se por um lado, o AM deveria estar desacoplado da view através do mecanismo Observer Synchronization, ao mesmo tempo ele é responsável por funcionalidades da view, por exemplo alterar cores para destacar erros de validação, habilitar e desabilitar widgets, etc. Por isso, ele às vezes precisa ter acesso à view, o que rompe o padrão observer.

MVP - A guinada

Como mencionado acima, o MVC não é para ser meramente substituído. Podemos notar que o problema do MVC não está em seu conceito, e sim no papel que suas entidades (model-view-controller) desempenham. Ao invés de substituí-lo, o Dolphin deu uma guinada de 60° para o MVP.

Entidades

View é um conjunto de widgets, que respondem às ações dos usuários e deixando para o presenter o tratamento desses eventos. Seu propósito é exibir dados do modelo.

Presenter se encarrega da lógica de apresentação, comanda o modelo e altera a apresentação de acordo com as regras da aplicação. É altamente acoplada com a View

Model são os objetos de negócio que representam o domínio do problema, armazenando os dados, interagindo com o banco de dados e serviços externos, lidando com a lógica de negócio. É totalmente ignorante da UI (portanto desacoplada do view/presenter).

Colaboração

Como mencionado antes, o MVP/Dolphin se assemelha muito ao Supervising Controller.

  • User triggered action: a view delega as entradas do usuário para o presenter;
  • Update display: o presenter executa alguma operação relacionada a UI, alterando seu estado interno, e a atualizando diretamente
  • Command: o presenter comanda o modelo da forma apropriada
  • Event (State Changed): o modelo atualiza o seu estado e dispara um evento apropriado
  • A view trata o evento - e (Query) pega os dados relevantes diretamente do modelo, para poder atualizar sua exibição.

Dando um passo atrás em direção ao AM-MVC, temos o padrão Passive View

  • User triggered action: a view delega as entradas do usuário para o presenter;
  • Update display: o presenter executa alguma operação relacionada a UI, alterando seu estado interno, e a atualizando diretamente
  • Command: o presenter comanda o modelo da forma apropriada
  • Event (State Changed): o modelo atualiza o seu estado e dispara um evento apropriado
  • O presenter trata o evento - ele obtém os dados relevantes do modelo, e atualiza a exibição da view.

Revisitando os problemas do MVC

  • O Dolphin resolveu o problema da aplicabilidade do controller, movendo suas responsabilidades para a view e para o presenter. A view ficou com a responsabilidade de responder aos eventos de mouse e teclado (entradas do usuário), enquanto o presenter ficou com a responsabilidade de comandar o modelo quando apropriado.
  • O Dolphin resolveou o problema da usabilidade, substituindo o Application Model pelo Presenter, o qual tem permissão para se comunicar diretamente com a view quando necessário.

Note que a view no MVP/Dolphin (Supervising Controller) se comunica com o modelo e se registra com seus eventos, enquanto no AM-MVC toda interação entre a view e o model é intermediada pelo 'Application Model'. O padrão Passive View (Fowler) é descrito de forma semelhante, com a intermediação view/model sendo feita através do presenter.

Interação

Vamos colocar os conceitos em prática, revisando a GUI de controle de volume que usamos na primeira parte desta série.

Relembrando: o usuário clica no botão "aumentar volume", e em caso de sucesso, o volume é aumentado em uma unidade, e a caixa de texto exibe o valor do volume atualizado. Se o volume exceder 12, a cor da caixa de texto deve ser mudada para vermelho.

O diagrama abaixo mostra como o MVP (Passive View) lida com este caso de uso.

Vimos na primeira partedesta série que o Application Model (AM) lidava com as regras lógicas (alterar a cor) já que a lógica de apresentação fazia parte de suas responsabilidades, e vimos também que o fato de o AM não poder mudar a cor da caixa de texto diretamente levava a um código deselegante, com o AM tendo que disparar um evento para o caixa de texto.

No MVP, o presenter se encarrega da lógica de apresentação, sendo o único a ter que lidar com a regra: agora, o presenter pode mudara cor da caixa de texto diretamente, e nenhum código adicional é necessário.

Outra coisa a se notar é que o presenter responde ao evento "VolumeChanged" e delega este evento para a view, ao invés de alterar diretamente a caixa de texto para atualizar o valor do volume. A razão para mostrar isso é estressar o fato de que nem todas as atualizações precisam ser iniciadas diretamente pelo presenter. Este deve acessar a view diretammente apenas para comportamentos que não se encaixem no padrão Observer Synchronization (foi o caso da mudança de cor de um widget específico, como resposta a uma lógica da aplicação).

MVC x MVP

Há dois MVC's - MVC Clássico e Application Model MVC, assim como dois MVP's - Supervising Controller and Passive View.

Desta forma, há 4 tipos de combinações MVC x MVP:

1) MVC Clássico x MVP PassiveView

2) MVC Clássico x MVP SupervisingController

3) AM-MVC x MVP PassiveView

4) AM-MVC x MVP SupervisingController

Se entendermos as diferenças entre o MVC Clásico e o AM-MVC; bem como as diferenças entre o MVP-PV e o MVP-SC, uma comparação entre o AM-MVC e o MVP-PV deve ser suficiente para entender as quatro variações.

AM-MVC x MVP-PV

View

No AM-MVC (assim como no MVC Clássico), todo widget é uma view. No MVP, a view é a tela em si. A view do MVP é uma composição de widgets, agrupados em um container de widgets, onde a tela em si é um agrupamento de widgets ou de containers de widgets.

Presenter

O ApplicationModel no AM-MVC e o presenter no MVP-PV são ambos responsáveis pela lógica de apresentação, e ambos agem como classes intermediárias entre o modelo e a view. A grande diferença é que o presenter é altamente acoplado à view, podendo modificá-la diretamente, enquanto o AM é pouco acoplado à view, devendo se comunicar com ela somente através de eventos.

olhando de relance, pode parecer que o AM-MVC foi fracamente projetado. Se o AM está encarregado da lógica de apresentação, como pode estar pouco acoplado à view?? A razão disso é que o AM lidava com um número indeterminado de pares view-controller, então o comportamento padrão era agir como um observer - assim ele não tinha que ser alterado cada vez que um novo widget fosse adicionado à tela. Já o MVP lida com uma única view (a própria tela), de modo que o presenter pode ficar altamente acoplado à sua view.

Ainda que o padrão para o AM era o baixo acoplamento com relação à view, em aplicações reais frequentemente isto era burlado, e por comodidade se permitia o AM ganhar acesso às suas views, quebrando o padrão observer.

Model

O modelo desempenha o mesmo papel em ambas as abordagens, uma vez que ele está desacoplado das responsabilidades de apresentação.

Ainda confuso?

O principal motivo para tanta confusão é o uso exagerado e às vezes errôneo do termo controller.

Algums pessoas não levam em consideração o fato que o Controller MVC versa sobre processar a entrada do usuário e traduzí-la em comandos do modelo. Ele não versa sobre mediar a comunicação entre o modelo e a view. Este equívoco é a razão pela qual o controller é frequentemente referido como 'Application Model' (ou 'Application Layer'), da mesma forma como o MVP é usado, porém sob a denominação de MVC.

É importante entender que a principal função do controller é interceptar a entrada do usuário, outras funções como comandar o modelo e alterar a view são apenas subprodutos desta função principal; da mesma forma, a função do presenter é lidar com lógica da aplicação, e funções como interpretar eventos são subprodutos de sua função principal.

Com a introdução das aplicações web, a necessidade de processar entradas do usuário ressurgiu. Agora, as entradas são enviadas para o servidor na forma de pedidos HTTP, e o controller ressurge na forma de novos padrões:

  • Application Controller: lida com aspectos relacionados ao fluxo entre páginas (page flow);
  • Page Controller lida com pedidos para uma página específica; e
  • Front Controller lida com todos os pedidos de uma aplicação Web.

MVP ou não MVP? Eis a questão!

Em sistemas que possuiem um domain model complexo, um application model e muitas views que espelham os dados do modelo, pode fazer sentido pagar o preço do MVP (aprender o padrão, analisar o design, etc). Ao escolher o MVP, devemos nos responder se é possível separar o presenter da view. Algumas perguntas podem ajudar na decisão:

  1. Espera-se que o sistema tenha suporte tanto para aplicações desktop como web? Neste caso, faz todo sentido usar um Presenter para interagir com os dois tipos de view.
  2. O sistema tem muitas views requerindo mais de um presenter? Neste caso, é mais racional criar uma única view, com vários presenters, que podem ser substituídos "on-the-fly".
  3. Quando não for suficiente testar somente o domain model e quisermos testar também o Application Model.

Caso as considerações acima não sejam aplicáveis, o presenter pode ser embutido na própria View. Também depende do ponto de vista do desenvolvedor.

Para alguns, o MVP melhora a usabilidade, a leitura e a facilidade de busca / navegação no código da aplicação. É mais fácil entender métodos "PlayButtonClicked" no presenter do que onPlayButtonClicked na view. Também é cômodo fazer a view lidar apenas com questões de visualização, deixando o presenter lidar com a maior parte da lógica de reagir aos eventos do modelo.

sábado, 12 de dezembro de 2009

Considerações Históricas sobre o Padrão MVC

Este post é o primeiro de uma série de traduções de artigos do blog Design Codes, que falam um pouco sobre a evolução do padrão MVC desde o final dos anos 70, até chegar aos dias de hoje, momento em que uma de suas variações - o MVP - está se popularizando, tendo inclusive sido citado como uma best practice no Google I/O 2009 para o desenvolvimento de aplicações GWT

A História do Padrão MVC (Model View Controller)

Neste artigo, caminharemos nas duas primeiras fases da evolução do MVC. Iremos revisar o padrão MVC Clássico desenvolvido por Trygve Reenskaug para o Smalltalk no final dos anos 70, e ver como ele evoluiu para o Application Model MVC (a partir de agora referenciado, neste artigo, por AM-MVC; uma tradução conveniente seria MVC com Modelo de Aplicação).

Clique Aqui Clique Aqui Clique Aqui


O Conceito MVC

A idéia por trás do MVC é fazer uma clara separação entre os objetos do domínio (model) e os objetos da apresentação (view/controller). Ele introduz o mecanismo "Observer-Synchronization" para
  • suportar múltiplas apresentações (observadores) de um mesmo conjunto de objetos de domínio (observáveis); e
  • para manter os objetos de domínio completamente desacoplados dos seus respectivos objetos de apresentação.
Este conceito foi largamente experimentado nas últimas três décadas, e mesmo com algumas significativas melhorias que foram introduzidas com o MVP, no final das contas o conceito permanece inalterado.

MVC Clássico

View

Os componentes view são os widgets da tela, podem ser botões, labels, etc. Seu propósito é exibir dados do modelo (usualmente um de seus campos). No MVC Clássico, componentes view se comunicam diretamente com o modelo.
Tenha em mente que estamos falando de widgets dos anos 80, não importando se eles eram clicados por mouse ou pressionados através do teclado.

Controller

Um controller é a entidade lógica que sempre tem uma view (widget) como par. Ele processa a entrada vinda dos dispositivos como teclado e mouse, e comanda o modelo conforme apropriado. O controller também se comunica diretamente com o modelo.

Model

O modelo diz respeito aos objetos de negócio que representam o domínio do problema. Geralmente, estes objetos armazenam dados, interagem com bancos de dados e serviços, e lidam com a lógica do negócio. Eles são completamente ignorantes com relação à UI, portanto eles não sabem absolutamente nada sobre a view nem sobre o controller.

Colaboração

O diagrama abaixo mostra como os objetos MVC colaboram entre si. Os objetos no diagrama representam uma UI bem simples, que possui apenas dois widgets (representados pelos pares "view widget"/controller) e um objeto de negócio (representado pelo modelo).
  • O controller recebe as entradas do usuário,
  • Se a entrada for relevante para o seu par widget (view), ele comanda o modelo,
  • O modelo executa alguma operação, altera seu estado, e dispara um evento.
  • O widget (view) responde ao evento, pega os dados relevantes do modelo, e altera a sua exibição.
image_thumb9
O que não é mostrado na figura:
  • A view está acoplada a um método do modelo, de forma que ela possa obter os dados toda vez que houver alguma alteração.
  • O controller e a view podem se comunicar diretamente um com o outro.

    • Nota do tradutor: A view, portanto, está acoplada ao controller, e o controller à view.

Interação

A GUI controle de volume mostrada abaixo tem um único caso de uso.
  • Gatilho: O usuário clica no botão "Aumentar Volume"
  • Cenário Normal: O volume é aumentado em uma unidade e a caixa de texto é atualizada de modo a exibir o volume atual.
A modelagem para esta GUI terá um par view-controller para cada elemento visual (botão, caixa de texto, label) e um objeto modelo para memorizar o volume. O diagrama abaixo mostra como os objetos MVC interagem.

Application Model MVC (AM-MVC ou MVC com Modelo de Aplicação)

À medida que o Smalltalk evoluia, uma nova entidade denominada 'Application Model' (AM ou modelo da aplicação) foi adicionada de modo a proteger o modelo e a view das responsabilidades da lógica de apresentação. O AM age como uma classe intermediária entre o modelo e os objetos da apresentação (view/controller), que deixam de acessar diretamente o modelo (domínio). Ao invés disso, eles acessam o modelo da aplicação (AM), e se registram para os eventos do AM.

Colaboração

  • O controller recebe as entradas do usuário,
  • Se a entrada for relevante para o seu widget, ele comanda o AM,
  • O AM por sua vez, executa alguma operação relacionada à UI, alterando o estado interno da mesma,
  • O AM comanda o modelo, o qual executa alguma operação de negócio, altera seu estado e dispara algum evento
  • O AM responde ao evento do modelo, propagando-o para o widget.
  • O widget responde ao evento do AM, peg os dados relevantes no AM e alterando a sua vizualização

Pra que a mudança?

Vimos que o MVC clássico funciona bem com a GUI do "Controle de Volume". O problema é que na vida real, a UI provavelmete terá casos de uso mais complexos. Para ilustrar, adicionemos um caso de uso a esta GUI: se o volume exceder 12 unidades, então a cor da caixa de texto deve mudar para vermelho. A questão é: quem deve ser responsável por este pedaço da lógica de apresentação?
Podemos empurrar isto para o modelo, de modo que dele dispare algum evento especial quando o limite exceder 12 (mas isso parece inadequado). Podemos extender o widget da caixa de texto, de modo que ela verifique o seu valor e, quando aplicável, altere sua própria cor. Soa melhor, porém ainda é preferível manter os widgets genéricos e ignorantes de qualquer tipo de lógica.
Exatamente por este tipo de situações que o AM foi inventado.
O diagrama abaixo mostra como o AM lida com a nova regra.

  • O usuário clica no botão "Aumentar Volume",
  • O controller comanda o AM para aumentar o volume,
  • O AM delega o comando para o modelo,
  • O modelo comanda o auto-falante e dispara o evento "DataChanged",
  • AM respond and delegate the event to the widget,
  • O widget verifica com o AM qual o volume atual,
  • O AM checa o volume com o modelo, retornando o valor para o widget, que atualiza seu estado.
  • O AM checa se o valor é maior que 12, neste caso dispara um evento ColorChanged, ao qual o widget responde alterando sua cor.
Um benefício de usar o AM é que ele pode armazenar dados da view, como a cor atual do widget, qual item em uma lista está atualmente selecionado, quais widgets estão habilitados ou desabilitados, e assim por diante.

Qual o problema com o AM?

O AM possui uma limitação: ele não tem permissão para manipular sua view diretamente, NÃO pode simplesmente mudar a cor da caixa de texto, ao invés disso, precisa disparar o evento "ColorChanged", e deixar que o widget responda ao evento.
O próximo post, 'Do MVC para o MVP', será mostrado como o Padrão MVP soluciona este problema.