MVC x MVP x Application controller

04/10/2015

0

Bom dia pessoal,
estou iniciando uma arquitetura nova para um novo projeto.
Como sabemos existem padrões de separação de lógica de interface, e creio que os mais conhecidos são o MVC e O MVP.
Conhecidas as diferenças conceituais entre eles gostaria de saber:
É possível utilizar um desses padrões para intercalar uma aplicação para mais de uma plataforma, por exemplo Windows e web?
em outras palavras: é possível utilizar um destes padrões para realizar a separação da lógica da aplicação, mas de forma que toda a lógica seja encapsulada e possa ser reaproveitada em uma aplicação Windows forms e Aspnet poe exemplo?
No que eu tenho encontrado pela net chego a conclusão de que o padrão MVC é mais ideal para aplicações WEB e o padrão MVP é mais ideal para aplicações Windows forms ou aplicações Web forms.
Alguém já tentou utilizar apenas um padrão para ambas as plataformas?
Ou ainda alguém já tentou utilizar o MVP com o controller do AspNet MVC implementando a View do presenter?
Ou ainda utilizar o padrão Application controller para controlar o fluxo da apresentação em ambas as plataformas, AspNet MVC e Windows forms com presenter?
Ghostbooster

Ghostbooster

Responder

Post mais votado

04/10/2015

Olá, tudo bem?

O padrão MVP é a "base" para outros como MVC e MVVM (este sim muito utilizado em aplicações mobile), sendo assim, todos pregam a divisão entre as responsabilidades de cada componente, variando apenas a camada específica que geralmente dependerá do tipo de aplicação.

O padrão MVVM foi desenvolvido focando aplicações que usam XAML na camada de interface, como Windows Phone e WPF, portanto sua aplicação é fortemente dependente dos recursos de Data Binding dessa linguagem (tente aplicar MVVM em WPF e Windows Forms para ver a diferença/facilidade).

No MVC temos a presença do "controlador", que em aplicações web é responsável por receber requisições do usuário e direcionar a ação para um determinado procedimento, retornando um resultado adequado (em geral, uma página web ou um conteúdo em formato JSON/XML).

Sendo assim, dificilmente você conseguirá aproveitar toda a lógica do seu código em projetos diferentes, pois parte disso depende de características intrínsecas da plataforma.

Porém, você consegue sim aproveitar partes consideráveis, em especial a camada Model, que se bem desenvolvida e unida a outros padrões, pode se tornar um conjunto de classes bastante genérico, que pode ser usado em vários projetos distintos.

Por exemplo, se suas classes Model forem do tipo POCO, e você usa o padrão Repository, facilmente você conseguiria aproveitar essa camada entre aplicações ASP.NET MVC e WPF.

Se você tiver uma aplicação orientada a serviços, que acesse um serviço RESTful via requisições HTTP, pode construir uma camada Proxy que juntamente com a Model para enviar e receber os dados.

Enfim, são muitas as possibilidades, espero ter contribuído.

Joel Rodrigues

Joel Rodrigues
Responder

Mais Posts

05/10/2015

Ghostbooster

Joel, muito obrigado.
Em pesquisas realizadas eu já havia constatado isso, queria apenas uma segunda opinião.
Desenvolvi um projeto utilizando o DDD que suporta no mesmo domínio múltiplos bancos de dados e pode ser aproveitado em múltiplas plataformas.

No meu caso implementei uma aplicação Windows Forms e uma ASPNet MVC, a mesma aplicação em mais de uma plataforma e que pode utilizar múltiplos bancos de dados (testei com SQL server e MySql), ou seja, a mesma base de código para todos os bancos.

A única questão é que para cada plataforma tenho que implementar uma VIEW e um CONTROLLER (ou PRESENTER), pois como você falou cada plataforma possui coisas muito intrínsecas. Algumas plataformas podem ter chamadas assíncronas, (tais como na WEB e em muitos caso em aplicações mobile) e outras podem trabalhar num ambiente mais síncrono como aplicações Windows. O simples fato de termos uma View modal já varia para cada plataforma.

No momento estou desenvolvendo um Framework (possivelmente será open source) que servirá como base para construção de aplicativos corporativos utilizando DDD e que possui um plugin para Visual Studio que irá facilitar a criação de algumas das classes.

Na construção já havia pesquisado formas de aproveitar a lógica de apresentação em mais de uma plataforma mas realmente as respostas que encontrei foram muito similares a sua.

Enfim, a parte que não varia (ou como dizia um professor meu, varia pouco) estando bem separada pode ser reaproveitada em múltiplos ambientes, variando somente o que é específico do ambiente.
Responder

05/10/2015

Joel Rodrigues

Legal sua iniciativa de criar esse framework, espero que dê certo. DDD é, na minha opinião, algo que aos "olhos destreinados" causa certo espanto e realmente é um tanto complicado de se entender em sua totalidade, apenas com muita prática é que se pega o jeito.

Realmente, dependendo de em que tipos de aplicação você quer aproveitar a lógica, dá pra compartilhar mais coisas. Por exemplo, se tratando de aplicações que utilizam um banco com conexão direta, seja local, em rede ou na nuvem, podemos compartilhar toda essa parte usando, por exemplo, Entity Framework Code First, alterando apenas o endereço do servidor em cada projeto.

Usando DDD isso fica bem facilitado, como você mesmo já prevê em seu projeto, pois temos toda a parte de Specs e unindo a mecanismos de Injeção de Dependência conseguimos injetar comportamentos específicos para um mesmo componente, dependendo do projeto.
Responder

06/02/2016

Ghostbooster

Boa noite Joel,
conforme eu havia falado tenho a pretensão de criar um Framework para auxiliar no trabalho com DDD.
entre as ferramentas que pretendo criar tem um gerador de classes.
O foco não é o gerador, mas sim o Framework.
O gerador pode ajudar na produtividade, mas pode-se trabalhar sem ele.

A idéia é o gerador dar um pontapé inicial e a partir daí o programador implementa aquilo que não é trivial, como validações e cálculos complexos.
Sendo que o gerador cria as classes das camadas de domínio tais como o repositório, a interface para o DataProvider.
Cria as classes da camada de aplicação, o presenter.
Como inicialmente estou usando o Nhibernate, cria também as classes de Mapeamento da Fluent API e implementa os métodos de listagem, mas o programador poderá implementar o seu próprio DataProvider.
Um problema de geradores de código pelo que já pesquisei é que ele tenta fazer coisas demais e outro problema é que o modelo pode ficar anêmico.
O diferencial do meu gerador é que você precisa do modelo para gerar o restante de código, assim o modelo não ficaria anêmico.
O caminho percorrido até aqui não foi simplesmente criar um gerador. Foi feita toda uma engenharia em cima do DDD e a partir disso começei a observar que algumas coisas ficam muito repetitivas e muito padronizadas. ex:
Se existe uma classe de repositório genérica e todas as derivadas, logicamente irão herdar dela, por que ter que fazer isso tudo manualmente se nunca irá mudar?
O caminho é sempre esse: 1 - criar uma nova classe, 2- declarar o namespace da classe base, 3- implementar os métodos obrigatórios da interface, ou métodos (abstratos),4 - criar as outras classes das demais camadas, 5 - Criar a IU.
Por esse motivo, resolvi criar o gerador de código.
Além disso como já disse o programador é livre para usar o Framework sem necessidade do gerador de código, porém terá o trabalho de adicionar as classes ao projeto, adicionar os namespaces e tudo mais.
Eu pretendo gerar como bonus as aplicações Windows Forms e AspNet MVC, mas o programador fica livre para implementar seu próprio front end, pois caa um gosta de utilizar de uma forma particular. AspNet MVC, outros HTML puro com Angular, etc...
Como você irá observar no vídeo, eu me utilizei de templates do Visual Studio, o que não é nenhuma novidade.
Mas também criei um plugin, e ele sim é uma aplicação a parte e que pode ser utilizada como plugin do Visual Studio.

O que você me diz disso?
Assista o vídeo.
OBS: Ainda tem muita coisa para fazer e a interface ainda não foi definida mas já envio para ver se você tem alguma sugestão ou crítica, ou se já viu algo parecido na net.

Link: https://youtu.be/LTQIVbVUG_k
Responder

12/02/2016

Joel Rodrigues

Opa, tudo bem? Desculpe a demora para responder, andei meio ausente do fórum.

Excelente seu trabalho, bastante completo e cobrindo tudo que propõe.

Tenho apenas um questionamento:

1) Por que você optou por criar Class Libraries para a IoC e o DataPovider? Por que não colocou, por exemplo, como pastas em um projeto para camada de Infraestrutura?

Grande abraço e parabéns.
Responder

12/02/2016

Ghostbooster

Boa noite Joel tudo bem?

O motivo de criar Class Libraries para a IoC e o DataPovider é justamente separar a camada por tecnologia utilizada.
Atualmente o DataProvider está implementando o NHibernate e o IOC está utilizando o Castle.
Se eu colocasse ambas em um mesmo projeto e futuramente eu quisesse acrescentar por exemplo um DataProvider entity ou ADO puro, eu estaria obrigado a levar para o meu projeto as dependências do NHibernate.
O mesmo aconteceria com o IoC. Se eu quisesse deixar de usar o Castle e optasse pelo Ninject, eu iria ser obrigado a levar as dependências do Castle sem que estivesse utilizando, ou teria que ficar removendo as dependências.

O que eu poderia fazer que a maioria do pessoal faz é criar na solution pastas separando as camadas: Domain, Infra estrututa, Cross Cuting, ....As pastas (virtuais) da solution iriam conter os projetos,mas de qualquer forma cada projeto seria fisicamente uma dll, ou seja, um class Library.
Ainda com relação ao IOC um motivo de fazer assim é porque eu implemento o Composition root, ou seja, eu tenho um módulo que tem a responsabilidade de criar o mapeamento das entidades necessário para o container Ioc.
Em todas as camadas da aplicação, a chamada do container Ioc é encapsulada em um façade: ContainerIOC.Obter<BLLCurso>().
No Ioc é que eu implemento uma interface IContainerIOC que por sua vez está utilizando o Castle.
Porém o restante da aplicação não sabe disso.
A vantagem é que se futuramente eu quiser trocar de container basta implementar, no Ioc, essa interface utilizando o ouro container.

Com relação ainda ao data provider:

Na class library do Domínio (ControleCurso.Dominio) tem o namespace (e pasta fisica no projeto): ControleCurso.Dominio.REPOSITORIO.INTERFACES
este namespace irá conter a interface para os dataProviders.

Ainda Na class library do Domínio (ControleCurso.Dominio), tem o namespace ControleCurso.Dominio.REPOSITORIO : este namespace contêm a implementação do repositório.
Qual o motivo disso? o Repositório pode possuir algum comportamento (e como possui no momento de armazenar as entidades, utilizando um state para decidir como persistir as entidades), este comportamento tem que ser igual independente da tecnologia (ou seja DataProvider) utilizada. Por esse motivo, os repositórios, usam o DataProvider, que são passados por dependency injection implementam o comportamento que tiverem que ter, e para persistir delegam ao DataProvider.

A implementação dessas interfaces de DataProvider estão justamente na class library separada, de acordo com a tecnologia (ControleCurso.DataProvider.NHibernate)

E a propósito, eu faço a nomenclatura dos projetos da seguinte forma, sempre que possível.

Nome do módulo . Camada . Tecnologia utilizada, ex:
ControleCurso.Dominio : independe de tecnologia.
ControleCurso.Aplicacao : independe de tecnologia.
ControleCurso.DataProvider.NHibernate, ControleCurso.DataProvider.Entity, ControleCurso.DataProvider.Memoria, ControleCurso.DataProvider.ADO (ou seja esses todos seriam class library separados)
ControleCurso.IU.WindowsFormsApp, ControleCurso.IU.AspnetMVC, ControleCurso.IU.ConsoleApp (ou seja esses todos seriam class library separados)

Essa forma de separar tem uma desvantagem:
Na distribuição da aplicação eu que legar para cada módulo 5 dlls + 3 dlls bases:
ControleCurso.Dominio
ControleCurso.Aplicacao
ControleCurso.DataProvider.NHibernate
ControleCurso.IU.WindowsFormsApp
ControleCurso.IOC

Core
Core.DataProvider.NHibernate
Core.IU.WindowsFormsApp

Isso gera uma necessidade de implementar algum tipo de controle de versionamento de dll para não correr o risco de utilizar uma ControleCurso.Dominio nova com uma ControleCurso.Aplicacao obsoleta, por exemplo.
Fora isso o projeto fica muito flexível.


Ainda tem coisas para modelar, mas o que você acha destas abordagens?
Algo a acrescentar? Alguma coisa que ficou confusa e pode melhorar?
Responder

12/02/2016

Joel Rodrigues

Excelente, imaginei que fosse por isso mesmo. =)

Sensacional, amigo. Novamente parabéns e sucesso no projeto, tenho certeza que ele ainda vai muito longe.

Agora resta dar um nome legal para o framework e começar a difundi-lo. Futuramente, quando você já tiver a versão 1.0 pronta, e se assim desejar, eu gostaria de lhe oferecer um espaço no canal que mantenho no Facebook e YouTube para fazer uma demonstração prática do seu framework. Será uma ótima oportunidade de divulgar o trabalho.

Para conhecer a página é só acessar o Canal .NET no Facebook e no YouTube.

Abraço.
Responder

12/02/2016

Ghostbooster

Muito obrigado Joel, será de grande ajuda mesmo.
Ainda tem muita mão de obra pela frente e tem uma ferramenta ainda que já comecei a idealizar.
Será um CRM que além de controlar os processos de desenvolvimento irá oferecer ferramentas de análise que ajudarão na detecção de bugs e ajudar a saber o impacto da alteração a ser realizada.
desta forma quando um atendimento for aberto, para uma determinada funcionalidade (caso de uso), o usuário do CRM que será o programador poderá saber onde exatamente ele deverá alterar no sistema
Da forma como implemento o framework, tenho como saber quais funcionalidade o usuário utiliza, mapeadas nas classes de aplicação, por isso a pergunta inicial deste fórum.
Assim quando o cliente abrir um atendimento, para uma determinada funcionalidade, o sistema já irá dar uma "Pré-análise" do que precisa ser feito.
Em anexo uma imagem de quais informações teriam no CRM, na tela de análise
O CRM é todo feito em cima do framework e ajuda no desenvolvimento com o framework.

[img]http://arquivo.devmedia.com.br/forum/imagem/456971-20160212-205138.jpg[/img]
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar