Padrão Model View Presenter
Model View Presenter (MVP)
• Padrão utilizado para separar a lógica da apresentação da apresentação propriamente dita.
• A idéia do MVP é que toda a lógica que normalmente iria ligar a IU com os dados seja movida para uma classe separada.
• Isso significa que a IU (Forms, UserControls, etc) se torna bastante “fina".
• No MVP, a IU é “burra” no sentido de que não há processamento embutido nela.
Arquitetura MVP
Componente Model
• O componente Model corresponde aos objetos que contêm a lógica do negócio.
• Esse componente não conhece nada acerca da apresentação.– Aspectos positivos: facilita o reuso da lógica do negócio
em diferentes contextos (ambientes).– Web, Smart Client, Mobile, WEB Services
• Idealmente esse componente, deve expor interfaces de forma abstrata, em vez de concreta.– Simplificação dos testes com objetos Mock– Isolamento da implementação do modelo
Componente View
• O componente View é uma estrutura composta de controles de interface com o usuário.
• Esse componente não contém qualquer comportamento que descreve como os controles reagem à eventos de sistema (i.e., a ações do usuário).
• A reação às ações do usuário é posicionada em um objeto separado, o componente Presenter.
• Os manipuladores para as ações do usuário ainda existem nos controles da IU, mas eles meramente passam (delegam) o processamento para o Presenter.
Componente Presenter
• O Presenter então decide como reagir ao evento notificado pelo componente View.
• Normalmente, essa reação corresponde ao envio de mensagens aos objetos componente Model.– Composto de classes do domínio e de classes de serviço.
• Conforme o presenter atualiza o modelo, o componente view é atualizado.
MVP versus MVC
• O MVP é uma variante do padrão MVC.• Qual a diferença?
– No MVC, o View “conversa” (no sentido de poder enviar mensagens) com o Model.
– No MVP, o View pode conhecer o Model, mas não envia mensagens para ele.
Prós & contras no MVP
• Há duas razões principais para usar o MVP:– Evitar a baixa coesão de uma Autonomous View.– Melhorar a testabilidade (essa é a mais convincente).
• Se testabilidade automática deve ser usada, isso conta positivamente para retirar o máximo de comportamento permanece do view.
• A vantagem da separação é que toda a complexidade comportamental é removida da interface gráfica, tornando esta última mais fácil de entender.
• Essa vantagem é “descompensada” pelo fato de que o controlador deve ainda ser fortemente acoplado à tela.– Nesse caso, há um “ponto de interrogação” grande acerca de
se vale à pena criar um objeto separado.
Prós & contras no MVP (cont)
• Aspectos positivos– Já que a lógica não está atrelada à IU, o MVP facilita a
utilização de um framework de testes.– Posiciona código de em seu lugar apropriado.– Aumenta o reuso do modelo de domínio.
• Aspectos negativos– Mais código para implementar.– Curva de aprendizado é acentuada.
Passive View x Supervising Controller
• O padrão MVP corresponde na verdade a dois outros padrões: Passive View e Supervising Controller.
• A diferença entre os dois está em quanto o componente View tem conhecimento acerca do componente Model.
• Quando o View não conhece nada acerca do Model e o Presenter realiza toda a lógica da apresentação, temos o padrão Passive View.
• Quando uma parte pequena dessa manipulação é feita pelo View, temos o padrão Supervising Controller.
Exemplo
Exemplo de View
• Esse é o componente View (CadastroDepartamentoView) para a funcionalidade de cadastro de departamentos.
CadastroDepartamentoView
• public class CadastroDepartamentoView extends JFrame implements ICadastroDepartamentoView
• O View aqui é uma subclasse de JFrame (formulário em Swing).
• O View deve implementar uma interface com a qual o Presenter irá interagir (o Presenter não interage com o View diretamente, apenas por intermédio dessa interface).
ICadastroDepartamentoView
public interface ICadastroDepartamentoView {
void desabilitarEntrada();
void habilitarEdicao();
void informarErro(String mensagem);
void modoAlteracao(); void modoInclusao(); void modoInicial(); void modoVisualizacao();
continua...
ICadastroDepartamentoView (cont.)
void limparCampos();
void setNome(String nome); void setSigla(String sigla); void setLocalizacao(String localizacao); void setVerbaAnual(Float verbaAnual);
String getNome(); String getSigla(); String getLocalizacao(); Float getVerbaAnual();}
ICadastroDepartamentoView (cont.)
• Note que ICadastroDepartamentoView não possui detalhe algum acerca da apresentação específica (e.g. Swing ou JSP).
• Isso aumenta a portabilidade do Presenter.• O View não conhece o Presenter diretamente, mas
notifica este último sobre a ocorrência de eventos de sistema;
Instanciação do Presenter
• Na sua instanciação, o objeto Presenter recebe o View e os DAO´s de que precisa como parâmetros.
• O Presenter é um ouvinte (listener) do View.
...
CadastroDepartamentoView form = new CadastroDepartamentoView();
CadastroDepartamentoController presenter = new CadastroDepartamentoController(form,
DepartamentoDAO.getInstance());
form.inscrever(presenter);
...
Modos do View
• O View pode passar por diversos modos (ou estados).
• Em cada estado, a aparência e o comportamento do View são diferentes.
• Esses estados se refletem em operações:– void modoAlteracao();– void modoInclusao();– void modoInicial(); – void modoVisualizacao();
• É responsabilidade do Presenter controlar o modo no qual o View deve se encontrar, em função das ações do usuário.
Eventos de Sistema
• Eventos de sistema ocorrem no View, mas são imediatamente repassados por ele ao Presenter.
public void inscrever(ActionListener listener) {
btnIncluir.addActionListener(listener);
btnConfirmar.addActionListener(listener);
btnCancelar.addActionListener(listener);
btnAlterar.addActionListener(listener);
btnExcluir.addActionListener(listener);
btnPesquisar.addActionListener(listener);
}
Eventos de Sistema
• É responsabilidade do Presenter decidir o que fazer como reação ao evento.– Ou seja, o Presenter implementa a lógica da apresentação.– Para ser um ouvinte do View, o Presenter implementa
ActionListener.
public void actionPerformed(ActionEvent e) {
String comando = e.getActionCommand();
if (comando.equals("Confirmar")) {
confirmarOperacao();
} else if (...
}
Uso de um Adapter
• Quando a lógica de IU é complexa, uma alternativa é criar adaptatores
• Adaptadores são objetos intermediários entre o view e o presenter.
• Servem para ajudar o presenter na execução da lógica da apresentação.
• Vejamos o próximo slide...
DomínioDomínioApresentaçãoApresentação
ModelModelViewView PresenterPresenter
NotificaçõesNotificações
Uso de um Adapter (cont)
Conclusões• Resumo da arquitetura MVP:
– View: exibe os dados e notifica eventos de sistema para o Presenter.
– Presenter: coordena a comunicação entre o view e a camada de serviços (ou camada de negócio) e é responsável pela lógica de IU.
– Model: os dados que devem ser exibidos ou editados na tela.
• Aspectos Positivos– Facilita a modificação da IU por designers gráficos.– Facilita o uso de TDD (Test Driven Design).– Separa adequadamente os aspectos da lógica da aplicação.
• Aspectos Negativos– Requer uma mudança na forma de pensar do desenvolvedor– Código é mais abstrato do que no estilo “Forms & Controls”
de programação visual.
Referências
• GUI Architectures– http://martinfowler.com/eaaDev/uiArchs.html
• Channel9– http://channel9.msdn.com/ShowPost.aspx?
PostID=313257
• Microsoft sobre MVP– http://msdn.microsoft.com/msdnmag/issues/06/08/
DesignPatterns/default.aspx
• MVC– http://en.wikipedia.org/wiki/Model-view-controller
Referências
• Passive View– http://www.martinfowler.com/eaaDev/PassiveScreen.html
• Supervising Controller (Supervising Presenter?)http://www.martinfowler.com/eaaDev/
SupervisingPresenter.html
• GUI Architectures– http://martinfowler.com/eaaDev/uiArchs.html
• Podcasts– http://polymorphicpodcast.com/shows/mv-patterns/
• Stub Generator (mais curiosidade do que realidade...)– http://www.polymorphicpodcast.com/tools/mvp-stub/
Material complementar
Modo Inicial
Modo Inclusão
Modo Visualização
Modo Alteração
Outros Padrões para Apresentação
• Forms and Controls• MVC (Model View Presenter)
Forms & Controls
• Os desenvolvedores escrevem os formulários específicos da aplicação que usam controles genéricos.
• O formulário descreve a disposição dos controles nele.• O formulário observa os controles e tem os métodos
manipuladores para reagir aos eventos interessantes originados nos controles.
• A edição simples de dados é realizada com a estratégia “Data Binding”.
• Alterações complexas são feitas pelos métodos manipuladores de eventos do formulário.
Code Behind
• ASP.NET traz uma forma de separar o comportamento da apresentação de seu layout: code-behind.
• No entanto, ainda há alguns aspectos negativos:– O code-behind ainda pode fazer as vezes do manipulador de
eventos em um ambiente orientados a eventos.• Forms & Controls
– É praticamente proibitivo realizar testes de unidades no código localizado nos code-behind.
• “TDD is difficult to use in some situations, such as graphical user interfaces”– Wikipédia para “Test Driven Development”
MVC
• MVC: Model-View-Controller• “modelo”; encapsula os dados• “view”- conceito de apresentação• “controller”- controla a apresentação
– comunicação com o usuário– gerenciamento de eventos
MVC
• Uso na plataforma JavaEE
Outro exemplo de MVP
• Suponha que haja a necessidade de apresentar dados sobre um objeto de negócio.
• Variance é um campo calculado• Cálculos fazem parte da lógica do negócio• Dica: não faça cálculos no código da IU
Interação entre Presenter e View
• O presenter solicita à view a exibição de algo sem assumir nada acerca de como essa exibição é feita– “O que” apresentar, e não “Como”
‘ Em vez dissoIView.TextBoxName.Text = Cust.Name
‘ Temos isso IView.DisplayCustomer(Cust)
Interação entre Presenter e View
• A view fornece notificações para o presenter acerca de ações relevantes do usuário.– O presenter é o responsável por iniciar a view.
Public Sub New(ByVal view As IView) _view = view AddHandler _view.FileNameChanged, AddressOf FileNameChangedHandlerEnd Sub