Estou tentando implementar o método MVP pela primeira vez, usando WinForms.
Estou tentando entender a função de cada camada.
Em meu programa, tenho um botão GUI que, quando clicado, abre uma janela de diálogo aberto.
Portanto, usando o MVP, a GUI lida com o evento de clique do botão e chama presenter.openfile ();
Dentro de presenter.openfile (), isso deve então delegar a abertura desse arquivo para a camada de modelo, ou como não há dados ou lógica para processar, ele deve simplesmente agir sobre a solicitação e abrir a janela openfiledialog?
Atualização: decidi oferecer uma recompensa, pois sinto que preciso de mais ajuda sobre isso, e de preferência sob medida para meus pontos específicos abaixo, para que eu tenha contexto.
Ok, depois de ler sobre MVP, decidi implementar a visão passiva. Efetivamente, terei um monte de controles em um Winform que serão manipulados por um Apresentador e, em seguida, as tarefas delegadas ao (s) Modelo (s). Meus pontos específicos estão abaixo:
Quando o winform carrega, ele deve obter uma visualização em árvore. Estou correto em pensar que a view deve, portanto, chamar um método como: presenter.gettree (), este por sua vez irá delegar ao modelo, que irá obter os dados para a treeview, criá-la e configurá-la, retorná-la ao apresentador, que por sua vez passará para a visão que então simplesmente o atribuirá a, digamos, um painel?
Seria o mesmo para qualquer controle de dados no Winform, já que também tenho um datagridview?
Meu aplicativo possui várias classes de modelo com a mesma montagem. Ele também suporta uma arquitetura de plug-ins com plug-ins que precisam ser carregados na inicialização. A visão simplesmente chamaria um método do apresentador, que por sua vez chamaria um método que carrega os plug-ins e exibe as informações na visão? Qual camada controlaria as referências do plugin. A visualização conteria referências a eles ou ao apresentador?
Estou correto em pensar que a visualização deve lidar com todas as coisas sobre a apresentação, desde a cor do nó da visualização em árvore ao tamanho do datagrid, etc?
Eu acho que eles são minhas principais preocupações e se eu entender como o fluxo deve ser para eles, acho que vou ficar bem.
Respostas:
Esta é minha humilde opinião sobre MVP e seus problemas específicos.
Em primeiro lugar , qualquer coisa com a qual um usuário possa interagir, ou apenas ser mostrado, é uma visualização . As leis, comportamento e características de tal visão são descritos por uma interface . Essa interface pode ser implementada usando uma IU WinForms, uma IU de console, uma IU da web ou até mesmo nenhuma IU (geralmente ao testar um apresentador) - a implementação concreta simplesmente não importa, contanto que obedeça às leis de sua interface de visualização .
Em segundo lugar , uma visualização é sempre controlada por um apresentador . As leis, comportamento e características de tal apresentador também são descritos por uma interface . Essa interface não tem interesse na implementação de visão concreta, desde que obedeça às leis de sua interface de visão.
Terceiro , como um apresentador controla sua visualização, para minimizar as dependências, não há realmente nenhuma vantagem em ter a visualização sabendo alguma coisa sobre seu apresentador. Existe um contrato acordado entre o apresentador e a visão e isso é declarado pela interface da visão.
As implicações do Terceiro são:
Para o seu problema, o código acima pode ser parecido com este em um código um tanto simplificado:
Além do exposto acima, geralmente tenho uma
IView
interface básica onde guardo aShow()
e qualquer visualização do proprietário ou título de visualização da qual minhas visualizações geralmente se beneficiam.Para suas perguntas:
1. Quando o winform carrega, ele deve obter uma visualização em árvore. Estou correto em pensar que a view deve, portanto, chamar um método como: presenter.gettree (), este por sua vez irá delegar ao modelo, que irá obter os dados para a treeview, criá-la e configurá-la, retorná-la ao apresentador, que por sua vez passará para a visão que então simplesmente o atribuirá a, digamos, um painel?
2. Isso seria o mesmo para qualquer controle de dados no Winform, já que também tenho um datagridview?
3. Meu aplicativo tem várias classes de modelo com a mesma montagem. Ele também oferece suporte a uma arquitetura de plug-ins com plug-ins que precisam ser carregados na inicialização. A visão simplesmente chamaria um método do apresentador, que por sua vez chamaria um método que carrega os plug-ins e exibe as informações na visão? Qual camada controlaria as referências do plugin. A visualização conteria referências a eles ou ao apresentador?
4. Estou correto em pensar que a visualização deve lidar com tudo sobre a apresentação, desde a cor do nó da visualização em árvore ao tamanho do datagrid, etc?
E quanto aos dados para nós clicados?
5. Se, ao clicar nos treenodos, devo passar pelo nó específico para o apresentador e, a partir daí, o apresentador trabalhará quais dados ele precisa e, em seguida, solicitará esses dados ao modelo, antes de apresentá-los de volta à exibição?
fonte
O apresentador, que contém toda a lógica da visualização, deve responder ao botão clicado como @JochemKempe diz . Em termos práticos, o botão click do manipulador de eventos chama
presenter.OpenFile()
. O apresentador pode então determinar o que deve ser feito.Se decidir que o usuário deve selecionar um arquivo, ele chama de volta para a visualização (por meio de uma interface de visualização) e permite que a visualização, que contém todos os detalhes técnicos da IU, exiba o
OpenFileDialog
. Essa é uma distinção muito importante, pois o apresentador não deve ter permissão para executar operações vinculadas à tecnologia de IU em uso.O arquivo selecionado será então devolvido ao apresentador, que continua sua lógica. Isso pode envolver qualquer modelo ou serviço que deve lidar com o processamento do arquivo.
O principal motivo para usar um padrão MVP, imo, é separar a tecnologia de UI da lógica de exibição. Assim, o apresentador orquestra toda a lógica enquanto a visualização a mantém separada da lógica da IU. Isso tem o efeito colateral muito bom de tornar o apresentador totalmente testável na unidade.
Atualização: uma vez que o apresentador é a personificação da lógica encontrada em uma visão específica , a relação visão-apresentador é IMO uma relação um-para-um. E para todos os fins práticos, uma instância de visualização (digamos, um Form) interage com uma instância de apresentador e uma instância de apresentador interage com apenas uma instância de exibição.
Dito isso, na minha implementação do MVP com WinForms, o apresentador sempre interage com a visualização por meio de uma interface que representa as habilidades de IU da visualização. Não há limitação sobre qual visão implementa esta interface, portanto, diferentes "widgets" podem implementar a mesma interface de visão e reutilizar a classe do apresentador.
fonte
O apresentador deve agir no final da solicitação e mostrar a janela openfiledialog como você sugeriu. Como nenhum dado é exigido do modelo, o apresentador pode, e deve, lidar com a solicitação.
Vamos supor que você precise dos dados para criar algumas entidades em seu modelo. Você pode passar o canal de fluxo para a camada de acesso onde tem um método para criar entidades do fluxo, mas eu sugiro que você lide com a análise do arquivo em seu apresentador e use um construtor ou método Create por entidade em seu modelo.
fonte