terça-feira, 22 de dezembro de 2009

Skoob - A rede social de leitores do Brasil


Esta mensagem que não é exatamente sobre desenvolvimeto de software, mas achei genial a idéia da aplicação Skoob: vc monta sua estante virtual, e avalia os livros que vc já leu. É uma ferramenta interessante, que pode ajudar a fazer boas compras, baseado na opinião de outras pessoas que já leram livros de seu interesse.

Quem se cadastrar essa semana tb está concorrendo a livros: http://www.skoob.com.br/promocao/codigo/119777

Eu definitivamente me tornei entusiasta da idéia dessa rede... Depois do trabalho, passei a última hora inteira apenas navegando entre os títulos. :-P

É interessante como idéias relativamente simples e novas tecnologias dão origem a novos produtos. apesar de conhecer e consultar bastante o serviço de avaliações da Amazon, o Skoob teve um apelo diferente.

Por ser uma rede social (fácil familiarização), e por permitir uma experiência única, de vc montar sua estante, com livros já lidos e com livros que se pretende ler, me senti de fato como se estivesse numa livraria; isso além de relembrar títulos que li na infância e adolescência, que já tinha até esquecido.

Acho que tb será interessante para saber o que meus amigos/conhecidos estão lendo, assim, além de identificar títulos em comum, há a possibilidade de conhecer e se interessar pelos títulos de pessoas conhecidas.

Por ser em português, ele ataca diretamente o nicho de mercado brasileiro. Fico na torcida que o modelo de negócio deles dê certo, bem como fico na torcida que nós desenvolvedores tenhamos sempre essa criatividade de reinventar o mundo e gerar novos negócios. Ganhar $$$ fazendo aplicações úteis para a sociedade.

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.

terça-feira, 15 de dezembro de 2009

Seu objeto está na sessão? Entenda o conceito Attached e Dettached Objects!

Esta manhã respondi no RioJUG uma dúvida sobre JPA que achei interessante registrar aqui no blog:

Em JPA, é interessante jogar uma luz sobre um importante conceito: attached/dettached objects. Quando um objeto persistente participa de uma sessão que ainda está ativa, ele se encontra no estado "attached". Depois que a sessão é encerrada (session.close() ou entitymanager.close()), o objeto passa para o estado "detached".

Basicamente, no estado detached, não há mais conexão com o banco, portanto nenhuma alteração realizada no objeto será efetivada no BD, e o objeto não pode mais tentar carregar informações adicionais do banco (por exemplo associações lazy que não tenham sido acessadas durante a sessão).

Estou falando isso, pois o conceito está diretamente vinculado ao papel da chamada merge:

o método recebe um objeto dettached, e retorna o objeto correspondente, vinculado à sessão. Quando o objeto dettached for uma nova entidade, o ORM em algum momento (não necessariamente no momento da chamada) irá realizar um insert no banco de dados. Caso seja uma entidade existente, é interessante obtê-lo através de uma chamada find:

Note que, pelo find, o objeto já é retornado participando da sessão. Uma vez que o objeto já participe da sessão, você pode continuar populando as propriedades desse objeto (attached.setXXX, attached.setYYY), todas as alterações feitas o objeto, DURANTE A SESSÃO serão efetivadas no banco. Resumindo: as alterações realizadas no objeto enquanto ele participa da sessão serão efetivadas no BD.

É legal fazer o seguinte teste: carregue um objeto que já esteja no BD, e realize as alterações nesse objeto. Ao final, apenas feche a sessão, sem a chamada em.merge (ela não é necessária, pois o objeto já estava attached). Logicamente dê commit na transação, caso aplicável. Depois verifique se as alterações foram efetivadas.

Por fim, o JPA fica muito mais divertido e produtivo quando entendemos melhor seu mecanismo de funcionamento, o ciclo de vida dos objetos, pois mapeamento objeto-relacional é seu conceito-base, mas seu poder é com certeza mais amplo.

Padrão MVP para Aplicações Web Cliente-Servidor

Este post é o quarto e último 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


O padrão Model-View-Presenter foi publicado em 1996 por Mike Potel, para se tornar o modelo de programação da próxima geração de aplicações Java e C++ da época. A arquitetura MVP era baseada no modelo de programação MVC clássico do Smalltalk, que era o mais comum naquele tempo, e que inspirou muitas outras bibliotecas e frameworks. Potel descreveu o MVP como um modelo unificado que era adaptável a aplicações multi-camadas e a múltiplas arquiteturas cliente-servidor.

Este artigo revisa o padrão MVP proposto por Potel, focando em sua implementação em aplicações Cliente-Servidor. Use os links acima para conhecer mais sobre a evolução do MVC. Ao final do artigo, existem links para blogs que dão exemplos de implementações do padrão MVP.

MVP em aplicações Desktop

O MVP de Potel inclui seis abstrações: View, Interactor, Presenter, Command, Selection, and Model.

É possível criar uma aplicação usando todas as seis abstrações:

  • Model: serve para interagir com o banco de dados, e armazenar informações.
  • Selection: usado para definir um subconjunto de dados selecionados.
  • Command: executar operações em uma Selection.
  • View: Desenhar a aplicação na tela.
  • Interactor: lidar com os eventos do usuário e invocar o Command apropriado.
  • Presenter: criar o Model, a View, as Selections, os Commands e Interactors, e gerenciar as interações entre eles para prover as funcionalidades da aplicação.

O modelo mais simples possível é ter apenas entidades Presenter, acumulando as responsabilidades do Model, da View e do Interactor. A View pode ser adicionada em seguida, para blindar o Presenter das responsabilidades de desenhar a aplicação na tela; Um próximo passo seria adicionar Interactors para tratar os eventos do usuário; e assim por diante, os elementos podem ser incrementalmente adicionados, sob demanda, à arquitetura.

Os desenvolvedores do Smalltalk adotaram uma variação MVP/Dolphin, que contém apenas os elementos Model, View e Presenter, com o Presenter acumulando as responsabilidades do Interactor, Command e Selection, ficando encarregado de responder aos eventos dos usuários, manter uma seleção de dados, e executar operações sobre esta seleção. Mais detalhes em Do MVC para o MVP.

Colaboração

Vejamos como o MVP pode ser usado como modelo base para uma GUI simples de uma aplicação chamada "Impressão de Registros". Há apenas um caso de uso: o usuário clica no botão imprimir, e o registro selecionado é impresso.

A modelagem MVP para esta GUI terá apenas uma View para desenhar a lista de registros, e um botão Imprimir; dois Interactors - um para capturar o clique do botão, e um para capturar a seleção de um registro na lista; um Command, para enviar o registro selecionado para a impressora (Model); um Selection, para armazenar o registro selecionado, e um Presenter, para criar a View, o Command, os Interactors, e realizar as interações entre cada entidade.

  • O usuário seleciona "Record-1"
  • o Interactor da lista captura o clique e faz a Selection apontar para Record-1
  • A view é atualizada para destacar o registro selecionado
  • O usuário clica no Botão Imprimir
  • O Interactor do Botão intercepta o clique e executa o PrintCommand
  • O Command verifica a Selection atual e envia para a impressora

MVP em aplicações cliente/servidor

No artigo descrevendo MVP, Potel sentencia que uma vasta gama de arquiteturas cliente-servidor podem ser modeladas através de variações simples do modelo MVP: em aplicações "fat-client", onde consultas SQL geradas no próprio cliente são mandadas através da rede; e em aplicações "thin-client", onde comandos são mandados para o servidor, e este atua sobre os comandos, para gerar o SQL apropriado.

Fatorando o Modelo

Uma forma de implementar a arquitetura MVP em aplicações Cliente-Servidor é dividir o modelo entre ao lado cliente e o lado servidor. Ou seja, haverão classes, em ambos os lados, representando um mesmo modelo conceitual. As entidades MVP residiriam todas no lado cliente, e o Modelo em si no servidor. Os modelos no lado cliente agem como proxies para os modelos reais que residem no lado servidor, nos quais ocorre a interação com os bancos de dados, e outras interações da lógica de negócio.

Nas aplicações atuais, o Interactor não mais é necessário, desde que os próprios Widgets sejam capazes de lidar com os eventos dos usuários (leia mais a respeito no tópico "problema da aplicabilidade" neste artigo). Já o Command e o Selection podem ser encapsulados no Presenter. Esta abordagem MVP simplificada é comum em arquiteturas de aplicações rich-client.

Em muitas aplicações de TI, o modelo reside inteiramente no lado cliente, enquanto o servidor é meramente um Sistema Gerenciador de Banco de Dados (SGBD), ou um web-service que encapsula o banco de dados.


Fatorando o Presenter

Outra forma de implementar uma arquitetura MVP em aplicações cliente-servidor é dividir o Presenter entre o cliente e o servidor: em arquiteturas fat-client, a lógica de negócios reside na parte do presenter que reside no lado cliente, com um presenter mais simples rodando no servidor; Em arquiteturas thin-client, a parte simples do presenter fica no lado cliente, enquanto o presenter no lado servidor lida com a lógica de negócios.

Em aplicações cliente-servidor onde o presenter onde o Interactor reside no lado cliente e o Command no lado servidor, o Interactor não tem como se comunicar diretamente com o Command. Neste caso, o interactor captura os eventos do usuário, e delega à contraparte cliente do presenter para lidar com eles. O presenter no lado cliente interpreta o evento e envia uma mensagem apropriada para sua contraparte no servidor, e esta sim executa o Command.

Exemplos de Aplicação MVP

Links Relacionados

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.

quinta-feira, 10 de dezembro de 2009

Anunciado o lançamento oficial do GWT 2.0

Google anuncia em 08/dez/2009 o aguardado lançamento do GWT 2.0: http://googlewebtoolkit.blogspot.com/2009/12/introducing-google-web-toolkit-20-now.html
Tradução para o português, por Fábio Miranda:

Introduzindo o SpeedTracer

Speed Tracer é uma nova e poderosa ferramenta de análise de performance para o Chrome que dá a você insights sem precedentes sobre o funcionamento interno de qualquer aplicação web - não apenas aquelas criadas com o GWT. Quer descobrir porque sua aplicação parece uma lesma? SpeedTracer pode ajudá-lo a encontrar a resposta. Veja uma demonstração no video:

(Ah, o SpeedTracer foi desenvolvido com o GWT!)

O que há de novo?

Este video destaca algumas das novas funcionalidades bacanas trazidas pelo GWT 2.0:

Abaixo são descritos em detalhes algumas das novidades do novo GWT SDK (kit de desenvolvimento GWT) e do novo GPE (Google Plugin para o Eclipse).

Mais eficiência com o novo Modo de Desenvolvimento e Compilações Intermediárias

  • GWT 2.0 melhora enormemente o cliclo de edição/atualização ao introduzir um novo método de depuração chamado modo de desenvolvimento, que permite que um projeto seja debugado com o navegador de sua escolha - sim, o seu navegador, e não um imposto pelo GWT! O modo de desenvolvimento conta com um novo plugin para o navegador, chamado Plugin de Desenvolvimento GWT, que torna possível ao projeto Java criar uma ponte de debug para qualquer navegador que tenha o plugin instalado. Detalhes técnicos à parte, esta nova forma de debugar simplesmente parece melhor.
  • Ao colocar a experiência de debug diretamente no navegador, o modo de desenvolvimento torna possível usar as ferramentas de desenvolvimento próprias de cada navegador, em combinação com o debug do Java. Ou seja, agora você pode debugar código Java no Firefox, enquanto simultaneamente usa grandes ferramentas como o Firebug, para visualizar as estruturas DOM e experimentos com CSS. O mesmo vale para o Ditto/Safari e assim por diante com os demais navegadores.
  • O novo GPE inclui suporte aperfeiçoado para iniciar e controlar o modo de desenvolvimento, incluindo uma nova View que registra as mensagens do logging diretamente numa Eclipse View (nota do tradutor: em versões anteriores, o log de mensagens do GWT era feito através do Hosted Mode). 
  • É possível iniciar o modo de desenvolvimento manualmente, através de uma interface Swing, que pode rodar completamente fora do contexto do eclipse, incluindo outras IDEs.
  • O modo de desenvolvimento também suporta debug em múltiplos navegadores, significando que é possível conectar a mais de um tipo de navegador em uma única sessão de debug. É uma ótima forma de rapidamente assegurar que o projeto funciona corretamente com a maioria dos navegadores, sem a necessidade de reiniciar o depurador Java.
  • E finalmente, o modo de desenvolvimento funciona através de uma rede. Por que isto é legal? Porque você pode facilmente testar os navegadores em sistemas operacionais diferentes daquele que você está desenvolvendo. Por exemplo, suponha que você esteja desenvolvendo em uma IDE no Linux. É possível, em uma simples sessão de debug, conectar através da rede para visualizar a aplicação que você está executando - e depurá-la - no Internet Explorer em um Windows, bem como no Safari em um Mac OS X, ou Chrome no Windows, ou Firefox no OS X... O ponto é que você pode desenvolver usando a plataforma de sua preferência enquanto pode debugar em cada combinação de navegador / sistema operacional que seus usuários possam ter.
  • Caso você necessite compilar frequentemente o código para Javascript - apesar de que esperamos que o modo de desenvolvimento irá reduzir dramaticamente que você tenha essa necessidade - você agora pode contar com a flag -draftCompile, a qual acelera o tempo de compilação, pois deixa de lado as otimizações de código. Para ser claro, você definitivamente não deverá mais fazer deploy de Javascript compilado, o que pode poupar tempo durante builds contínuos intermediários (que não sejam builds de produção).

Interfaces Declarativas com o UIBinder

  • GWT 2.0 introduz numa nova forma mais produtiva e poderosa de construir codigo de interfaces de usuário, chamada UIBinder. Ela facilita a separação dos aspectos visuais da UI da lógica da aplicação. Para construir a UI, simplesmente junte HTML e elementos de widgets GWT de forma declarativa em um template XML UIBinder (um arquivo na forma *.ui.xml). Você pode então colocar a lógica da aplicação em um arquivo *.java correspondente.
  • UIBinder torna muito mais fácil envolver designers web mais diretamente no workflow de desenvolvimento. Por exemplo, desenvolvedores podem copiar e colar mocks HTML fornecidos por um web designer. 
  • Nós também temos notado que alguns designers web gostam de editar templates UIBinder diretamente e usar o ciclo de edição/atualização rápido do modo de desenvolvimento à medida que eles fazem experiências com a UI. É bem mais divertido modelar usando widgets interativos do que mocks HTML passivos.
  • Incorporar seus próprios widgets customizados em um template UIBinder é exatamente igual a usar quaisquer um dos widgets nativos do GWT.
  • UIBinder também ajuda a prevenir bugs subtos, como erros de digitação dos IDs, de colocar em produção código com bugs, ao validar em tempo de compilação todas as referências cruzadas entre os pares de arquivo .ui.xml e o .java.
  • O GPE agora vem com wizards UIBinder, auto-completar de código, e refactoring para ajudar a usar o UIBinder de forma eficiente.

Visual perfeito ("pixel-perfect") com painéis de layout

  • Alcançar o visual (look and feel) exatamente do jeito que você deseja é algo que tradicionalmente requer artemanhas e truques com HTML e CSS. Antes de GWT 2.0, mesmo os widgets GWT não eram capazes de abstrair totalmente algumas das dores de cabeça relacionadas a layout que poderiam ocorrer. Porém, GWT 2.0 introduz novos painéis de layout que realmente tornam possível criar o layout que você deseja. A aplicação de exemplo "Mail" no GWT SDK foi atualizada de modo a mostrar como isto funciona.
  • Painéis de layout criam um sistema de layout no topo do CSS padrão. Devido ao fato que eles trabalham sobre o CSS (e não ignorando o CSS), painéis de layout continuam a funcionar de forma previsível mesmo na presença de estilos CSS customizados que você necessite incluir. E devido ao fato que layout baseado em CSS é tratado nativamente dentro da engine de renderização do navegador, nenhum JavaScript precisa ser executado durante o layout. Como resultado, o layout é mais rápido e fluido: você poderá notar especialmente a velocidade ao redimensionar a janela do navegador.
  • Como é de se esperar, painéis de layout funcionam especialmente bem com o UIBinder. Com apenas algumas linhas de XML, você consegue criar layouts realmente sofisticados, incluindo transições animadas, divisórias, e assim por diante.

Melhorias de Código

  • Uma nova funcionalidade chave no GWT 2.0 é o code-splitting guiado pelo desenvolvedor. É muito mais fácil explicar com uma analogia: quando você está assitindo a um filme online, você definitivamente não deseja baixar o filme inteiro antes de começar a assitílo, certo? Você quer que o filme inicie instantaneamente, e o resto pode ser baixado aos poucos. O mesmo é válido para aplicações web. Iniciar aplicações não deve fazer você sentir como se estivesse instalando alguma coisa. Você apenas quer ver as coisas acontecerem ao clicar em um hyperlink. Cod Splitting é uma ferramenta que pode ajudá-lo a obter exatamente isso.
  • Pode soar complicado, mas code splitting é na verdade fácil. Apenas encontre um local em sua aplicação onde você gostaria de retalhar parte do código e usar o novo e mágico método GWT.runAsync() para criar um split point. Ao ir continuamente adicionando split points toda vez que isto fizer sentido, você pode de forma fácil e segura retalhar a sua aplicação de forma a assegurar que o download inicial inclua somente a quantidade mínima de código necessária para iniciar a aplicação.  O compilador automaticamente organiza os fragmentos de código adicional para serem baixados mais tarde. E, ao invés de manualmente dividir o código "na unha" através de declarações <script> o GWT automaticamente faz o trabalho pesado de assegurar que todas as dependências necessárias sejam baixadas na ordem correta. Como exemplo, a aplicação Showcase incluída no GWT SDK foi atualizada para mostrar o funcionamento do code splitting.
  • Além de code splitting, há também melhorias fundamentais à habilidade do compilador em produzir JavaScript. Adicionamos otimizações para tornar o código compilado menor e mais rápido. se você já possui projetos GWT existentes, pode experimentar grandes benefícios simplesmente fazendo um upgrade, recompilando, e provando que suas aplicações iniciam e executam mais rápido. GWT 2.0 inclui otimizações de grande impacto, e já vimos reduções no tamanho do JavaScript compactado variando entre 3% e mais de 20%.

Otimização de recursos com o ClientBundle

  • ClientBundle extende e generaliza o padrão de agrupamento de recursos que foi criado com o ImageBundle no GWT 1.4. Com uma simples interface Java, você pode em tempo de compilação otimizar e embutir recursos diretamente em código JavaScript compilado. Por exemplo, ao embutir imagens, você consegue evitar ineficientes round-trips de HTTP. ClientBundle prov~e suporte a uma ampla variedade de recursos, incluindo imagens, texto e até mesmo CSS>
  • Você ouviu bem , CSS. CssResource é uma nova e poderosa framework para gerenciar estilos. Suporta uma nova sintaxe extendida de CSS para definir sprites, named constraints, escopos, seletores condicionais e assim por diante. Ela também otimiza agressivamente seu CSS ao remover comentários e espaços em branco, e ao obfuscar nomes de classes.
  • ClientBundle é também extensível. Você pode criar seus próprios tipos de recursos e enganchá-los para dentro da framework ClientBundle para manter suas interfaces de recursos coerentes enquando agrupa quaisquer tipos de recurso que você considerar conveniente.

Agradecimentos Especiais

GWT 2.0 é o ápice de muitos meses de desenvolvimento colaborativo, e em nome de todo o time GWT, nós gostaríamos de agradecer ao time do WebKit, com os quais trabalhamos de perto e adicionamos a instrumentação de baixo nível necessária para tornar possível o Speed Tracer.
E, como sempre, profundos agradecimentos à comunidade de desenvolvedores GWT, muitos dos quais bravamente baixaram o GWT diretamente do trunk SVN, testando as novas funcionalidades ainda em progresso, e auxiliando a encontrar bugs, e até mesmo submetendo correções para os bugs que encontravam

Get Started!

Acredite ou não, nós nem chegamos perto da superfície de todos os novos recursos que o GWT oferece. Como sempre, GWT é Open Source e gratuito para utilizar. Esperamos que você dê ao menos uma olhada no GWT 2.0.
Happy Coding! Nos vemos online!