380 likes | 514 Views
Padrão Model View Presenter. edubezerra@gmail.com. M odel V iew P resenter (MVP). Padrão utilizado para separar a lógica da apresentação da apresentação propriamente dita.
E N D
Padrão Model View Presenter edubezerra@gmail.com
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.
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 compostade 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 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...
Uso de um Adapter (cont) Apresentação Domínio Notificações Adapter Model View Presenter
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/
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 disso IView.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 FileNameChangedHandler End Sub