Perguntas sobre MVC Desktop! Existe solução? (+ MVP,MVC WEB,Observer e Exception's)

Entendi Lavieri… bem bacana a sua explicação.
Muito legal. Vou fazer o seguinte: Vou tentar firmar a sua idéia ajudando alguém que há alguns dias não aparece no tópico, a menina da Agenda, lembra dela?
Vou tentar fazer uma agenda usando esse esquema e vou colocar o código aqui. Só peço um pouco de paciência que meu raciocínio é mais lento que botar fogo no gelo! :shock:

Mas depois dessa explicação vou ficar com :oops: se não conseguir!!!
Forte abraço, breve estarei postando o código! :wink:

Esse tópico deve ser um dos melhores daqui, aprendi mais algumas coisas que não sabia só de dar uma olhada nos posts. :roll:

Olá rapazes,

Pedro, não precisa se preocupar em implementar a agenda. Citei a agenda como um exemplo também para aprender melhor a teoria… tinha dúvidas parecidas com as suas.
Gostei da explicação do Lavieri ficou bem interessante… (não dá sono, como disseram aí acima hihihihi!)
Vou tentar também implementar do meu jeito e posto aqui!

Obrigada! :smiley:

Oi meninos! Procurei mais sobre o assunto, não poderia deixar de comentar uma coisa que percebi: existe uma confusão muito grande entre MVC x MVP.

[quote=Lavieri]o seu main, faz parte do controle… ele é o que monta o inicio da aplicação e da um start…

se o controle que cuida de integrar a visão “v” ao modelo “m” é o controle “c” … então “c” que tem que instanciar e cuidar dos dois …

melhor do que colocar os passos do controle no MAIN é fazer assim

public static voi main(String args[]) { new ControlePrincipal().start(); }

ai no caso o controle principal seria assim…

[code]
public class ControlePrincipal() {

private Modelo modelo;
private ModeloBeanInformacao umBeanContendoInfos;
private Visao visao;

public void start() {
montaModelo();
montaVisao();
ligaAInformacaoDaVisaoComOModelo(); //aqui foi por minha conta, para deixar o exemplo mais rico.
mostraVisao();
}

private void montaModelo() {
this.modelo = new Modelo();
}

private void montaVisao() {
this.visao = new Visao();
modelo.addModeloListener(new ModeloListener() {
void notificador(ModeloEvento me) {
visao.façaAlgo();
}
});
}

private void ligaAInformacaoDaVisaoComOModelo() {
this.umBeanContendoInfos = new ModeloBeanInformacao ()ç
visao.setBeanDeInfos(umBeanContendoInfos);
visao.addVisaoListenerBotaoSalva(new VisaoListenerBotaoSalvar() { //isso é apenas um exemplo didatico
public void botaoClicado(EventoVisaoBotaoSalva evento) {
this.modelo.salvar(evento.getBeanContendoInfos()); //#1
}
});
}

private void mostraVisao() {
visao.setVisible(true); //observação, nesse exemplo, o objeto Visão já é um JFrame,
//se ele não for um, ai vc muda a montagem, ou adiciona um montarJanlea(); antes do mostrarVisao() =P
}
}[/code]

ai o que vc for precisando fazer a mais, vc vai fazendo a ligações com novos controles

no caso ilustrativo do #1 … ai clicar no botão da VIEW, o controle recebe o evento… pega a informação que o modelo precisa do evento (o objeto contendo as informações, esse objeto é um objeto de modelo) … pega este objeto e envia para o this.modelo, para que ele salve o objeto… esse método modelo.salvar(bean); pode disparar um evento, e como a visão esta escutando o evento do modelo, o controle nem precisa se preucupar com a resposta do modelo, pois ela já vai direto pra visão… visto o que foi setado em “montaVisao()” quando adicionou-se a visão como listener…

O papel do controle é esse… intermediar, fazer o meio de campo…

dizer… BOTão da VIEW 1 … vc vai representar tal ação no modelo

ele serve pra isso ocontrole… receber informação dos dois lado… e fazer as ligações… enviar para os lugares corretos
[/quote]

Isso é MVP - Passive View… Pode conferir neste link
Por sinal, muito bem mostrado pelo Lavieri. :smiley:

Outro exemplo de confusão está em outro link postado aqui neste tópico mesmo. Neste link diz “estrutura MVC” mas na verdade é uma ‘estrutura MVP’ a qual não consigo definir se é Passive View ou Supervising Controller. A mesma coisa vale para este outro link. Ambos não usam o Observer, simplesmente intermediam o meio de campo. - Agem como Presenter, sem Observer.


Particularmente o MVP ‘ao meu olhar feminino’ é a melhor opção para o caso de construir uma Agenda (só olhar a img acima). Mas ainda estou preocupada quanto a esse ‘bean’ solto por todo lado… :? Não seria mais adequado (isso falando em MVP, my case ) existir uma interface implementada pela visão com gets/sets dos TextFields para que o Presenter ao receber o evento do botão possa colher os dados e passar para os set’s do modelo? Evitaria esse bean e teoricamente mais correto… tô errada? me falem!!!

Obrigada meninos fico no aguardo. :smiley:

Na prática MVC é legal para frameworks. Swing, JSF , etc… e MVP é legal para como as aplicações interagem com esses frameworks.

O pessoal do swing criou-o em MVC. mas agora eu só preciso na realidade lidar com os modelos para injetar dados, e com a visulaização (desabilitar , tornar invisivel, etc…) Aqui entra o MVP. O Presenter é responsável por consultar o modelo dele e/ou alterar a visualização em conformidade.
Por exempplo, só habilita o combo de cidades se o cara já escolheu o pais. Repare que ainda estou ouvindo eventos, mas eventos de alto nivel “alteração do pais” e não “o combo xpto foi modificado”. Como eu transformo um change event do combo num evento de negocio que o presenter entende ? Na view do MVP. A view do MVP é um cara super bom que conhece todo o MVC do cliente gráfico. Ele tanto pode manipular modelos como componentes.Ele canaliza e traduz os eventos em conformidade com as regras de apresentação. Por isso que temos dois andares : cliente e apresentação. Os comandos do cliente são agnostios sabemos que tal menu foi clicado ou tal botão foi apertado, etc, mas não sabemos o que isso significa. Cabe à camada de apresentação saber. Podemos usar um MVC na camada de apresentação, mas o MVP tem mais vantagens práticas.
Frameworks web já implementam a camada view para HTTP pela injeção de dados e outas coisas assim, em swing é mais complexo , não ha nada pronto assim , apenas frameworks como o thinlet que dão todo o frameowork mas de forma abstrata ( não se é um JButton do swing ou um button do AWT por detrás do evento. )

A vantagem do MVP é que tanto o M como o V podem ser abstraidos de forma genérica e abacamos apenas ter que implementar o presenter. Por exemplo, para formulários, teriamos um view que já sabe trabalhar com formulários que dá acesso aos valores dos campos, e ás acções que o usuário executor como salvar, deletar etc… no presenter teremos métodos como

 save(AlgumObjectoDeContexto contexto) {
     // le os dados do formulário e poe num objeto
     ClienteForm clienteForm = contexto.getFormInstance(ClienteForm.class); 

    // valida formulário 

   // se tudo está ok, transforma clienteForm para o objeto Cliente
  
   // salva

      ClienteCRUDService service = ...
      service.save(cliente);   
}


@Trigger("//pais[changed]")
onPaisChanged(AlgumObjectoDeContexto contexto){
 ClienteForm clienteForm = contexto.getFormInstance(ClienteForm.class); 

       UIComponente uic = contexto.find("//cidades");

      uic.setVisible(clienteForm.getPais()!=null);
}

Como se vê é preferivel ter um conjunto de interfaces que abstraem muito do cliente UI, Contudo isso não é obrigatório.
Poderiamos ter um modelo mais simples onde do contexto tenho um objeto Form e nesse objeto tenho get/set dos campos (semlhante a um httprequest em web).

É bom também que se usem bens de visualização. O clienteform é um bean simples ( sem composição) onde pais e cidade são campos “não relacionados”. O Presenter pode transformar isso para um objecto cliente concreto que tem, por exemplo, associação a Endereço e Endereço que tem esses dois campos. O UIBeans são uteis para facilitar a leitura dos dados da tela onde não queremos nos preocupar com as relações. Além disso permitem que sejam adicionados campos de controle (flags / hidden) que são apenas usados pelo presenter e não têm relação com as entidades em si.

Para quem trabalha com Spring, ou Struts ou algum web framework conhece este mecanismo onde apenas se implementa um classe. As pessoas chamam ela de controlador, mas na realidade é um presenter. No Struts 1 isso é ainda mais obvio porque existe um encapsulamento explicito num objeto ActionForm ( que equivale ao meu clienteForm no exemplo).

Resumindo, se vc for implementar com MVP vc precisa de construir o V que se ligue ao swing. e depois só implementa o presenter para cada caso. Isto pode não ser tão trivial como parece, mas tb não é nenhum bixo de sete cabeças.

Isolando o presenter do swing, vc acaba ganhando um mecanismo de presenter que funciona para todos os MVC que existem. Portanto, se um dia vc quiser mudar para SWT ou AWT ou mesmo javaFX, em tese vc consegue. Este conceito é o que o thinlet aplica se bem que - até onde sei- ele só gera AWT.

Olá dedicados meninos… :wink:

Sergio, se entendi direito o que tentou expor teoricamente aí na postagem anterior você defende o que o Lavieri falou, estou errada?
Defende o uso de um bean para trazer os dados da visão até o presenter e vice-versa, certo? Mas ao invés dele, porque não usar interfaces?
Veja, vamos ver se entendi o que uma parte do MVP implementado:

  1. MVP Está dentro de uma camada (assim como o MVC)? Trocando em miúdos, MVP está em uma camada ou mais, mas não está jampeando duas, três, quatro camadas?
  2. Visão e Presenter são fortemente acoplados?
  3. Presenter instacia a visão e o modelo?
  4. Presenter modifica/consulta diretamente os componentes da visão chamando métodos gets/sets da interface dela?
  5. Presenter tem as funcionalidades (classes Listeners) dos componetes da visão, por exemplo, dos botões e o que eles farão?
  6. Presenter consulta/modifica o modelo por chamada direta aos métodos?
  7. Presenter escuta os eventos de notificação de mudança de estado do modelo? (Isso é para dar extensibilidade ao sistema, não?)
  8. No MVP a visão é ‘burra’. Ela possui componentes SWT, ou AWT, ou GWT, ou JavaFX, que simplesmente não sabem fazer nada a não ser interagir/capturar dados do usuário?
  9. A visão implementa uma interface com os métodos necessários para que seja usada pelo Presenter?
  10. A visão possui métodos set/getListener() para receber os listener’s do Presenter que escutarão os eventos lançados pelos componentes presentes nela?
  11. O modelo é a lógica da Apresentação e ponto?

E lembrem-se: no momento é uma Agenda em Swing… :lol: Quero aprender o melhor possível o básico… se a fundação é boa, o prédio não cai. :oops:

Pra mim o que diferencia o MVC do MVP é:

  1. MVC é para um componente. MVP é para vários componentes (ou widgets, como quiserem).
  2. MVC a visão escuta o modelo. MVP o presenter escuta o modelo.
  3. MVC o controle só transforma os “user gestures” em situações reais para o modelo. No MVP o presenter, além de fazer o que faz o controler do MVC ele também fala com a visão.

Vejam:

<<< MVP != MVC >>>

Agora uma pergunta final, depois de tantas acima que ainda não tem resposta (e olha que procurei nas postagens anteriores): Essa seta “Seleciona a View” está errada na imagem do MVC não?
Controle não fala com a visão por chamada direta, certo? elá deveria então ser tarcejada, não?

Obrigada por me aturarem… :smiley:

[quote=ingridfarabulini]Olá dedicados meninos… :wink:

Sergio, se entendi direito o que tentou expor teoricamente aí na postagem anterior você defende o que o Lavieri falou, estou errada?
Defende o uso de um bean para trazer os dados da visão até o presenter e vice-versa, certo? Mas ao invés dele, porque não usar interfaces?
[/quote]

Não sei de onde inferiu que usei beans no exemplo atráz. Como vc pode saber se ClienteForm é um bean ou uma interface (thats right, não pode, :slight_smile: )
Na prática tanto faz. Ou vc vai ter um bean com get/set diferentes para cada formulário (porque cada um tem campos diferentes) ou vc vai ter uma interface de get/set
para cada formulário e um mecanismo que responde por essa interface ou vc vai ter um objeto de contexto genérico mais parecido com um Map.
A escolha do bean não é diferente da interface na prática, apenas na implementação.

sim

Não. O presenter sabe qual é a visão, mas a visão não precisa saber qual é o presenter. O presenter precisa ouvir eventos da visão, mas isso pode ser feito por um mecanismo do tipo Observer.
Não ha necessidade de acoplamento.

Sim, mas não precisa ser explicitamente. como mostrei atraz eu mudei o estado de enable de um componente sem ter que saber qual ele é.
Nem mesmo preciso saber que é um componente swing.

sim. o presenter terá vários métodos que são invocados quando os ventos acontecem.

[quote]6. Presenter consulta/modifica o modelo por chamada direta aos métodos?
[/quote]

sim.

[quote]7. Presenter escuta os eventos de notificação de mudança de estado do modelo? (Isso é para dar extensibilidade ao sistema, não?)
[/quote]

Exacto. Na prática não é muito usado.

[quote]8. No MVP a visão é ‘burra’. Ela possui componentes SWT, ou AWT, ou GWT, ou JavaFX, que simplesmente não sabem fazer nada a não ser interagir/capturar dados do usuário?
[/quote]

mais ou menos burra. Ela sabe que clicar no botão x significa “salvar” e no y significa 'sair". Ela apenas não sabe o que fazer.
O mecanismo que traduz o clique no botão para a chamada ao método no presenter está na visão.

[quote]9. A visão implementa uma interface com os métodos necessários para que seja usada pelo Presenter?
[/quote]

sim. Normalmente um objeto não chega. É preciso ter um mecanismo mais ou menos como o de um servlet.

[quote]10. A visão possui métodos set/getListener() para receber os listener’s do Presenter que escutarão os eventos lançados pelos componentes presentes nela?
[/quote]

Depende de como implementar. Pode fazer dessa forma.

Não. O presenter é a logica de apresentação (presentation ~presenter)
O modelo do MVP normalmente é adaptaer para um serviço , um façade , um besiness delegate , um dao ou um repositorio. Não é um objeto de UI como o M do MVC.

Não. Não tem nada a ver.

No MVC o modelo é do V, e o C é apenas um mediador. A logica está contida no M. ( o V é o “master”, todos trabalham para que ele funcione)
No MVP o V é do presenter e a logica está no presenter. O mediador é o M.( O P é o “master” todos trabalham para ele).

NO MVP o V não passa de um grande adpater da tecnologia de UI, no caso swing. E o M não passa de um adpater para a camada abaixo ( a de negocio).
No MVC não adapters. Cada item tem o seu papel proprio e as coisas só funcionam quando os 3 funcionam coerentemente.

Sim, o presenter é muito mais “controlador” que o controler do MVC. Infelizmente os nomes do MVC foram mal escolhidos ( deveria ser algo mais como Renderização-Componente-Dados)

Imagine um sistema de chat. Quando A envia uma mensagem a B ela chega pela camada abaixo do apresentação, ela chega pelo M do MVP. O M então precisa avisar o P que chegou uma mensagem para que o P faça algo com ela. Outro exemplo seria o sistema através do M avisar que a rede caiu e o P , sabendo isto, faz aparecer algum icon em algum lugar da V.
É por isso que o M pode ter que avisar o P. O P controla o estado de apresentação e a apresentação não depende apenas do que o usuário faz, depende tb do que o sistema faz e do que outros usuários fazem quando o sistema é multi-usuario. É por isso o MVP é mais natural para a camada de apresentação que o MVC.

Opa tudo bem ai pedromuyala, cara achei o topico muito bom parabens pela iniciativa, fiquei muito interessado na analise e no projeto que vc está fazendo… ainda não tive tempo de ler as 14 paginas do topico… será que vc poderia me mandar o seu projeto para ver como está ? Me responda por MP se possivel.

Obrigado.

Opa, fala Alchemist, tudo bom contigo?

Então na verdade não existe nenhum projeto em desenvolvimento. O único projeto real mesmo até o momento é a Agenda da Ingrid ( aí de alguns post’s atrás! :smiley: )
Na verdade, quando criei o tópico tinha o objetivo de conseguir esclarecer de uma vez por todas algumas dúvidas que tenho de MVC desde que o conheci… mas nunca imaginaria que se tornaria essa coisa monstro que está, como pode ver você mesmo. Sempre acreditei que o MVC ajudaria da melhor forma os programadores, engenheiros, arquitetos de software a desenvolverem sistemas com qualidade na hora de realizar manutenções ou alterações. Mas já vi que não é bem isso que ocorre. Se ler todos os post’s vai ver que cada pessoa entende MVC de uma maneira diferente, não é criticando, muito pelo contrário, é até legal que existam diferentes idéias… o triste é que não se tem um acordo geral. Imagine uma grande empresa de software que desenvolve um único sistema, porém as diversas equipes entendem uma mesma teoria de diferentes maneiras… se essas equipes mudarem, por força maior mesmo, na hora de integrar ou dar manutenção, alterar, aumentar, testar o sistema… meu Deus, e agora, quem tem razão: A equipe que entende MVC x, a equipe que entendia MVC y ou z?

Acredito que o tópico tem ajudado muita gente principalmente a pensar nisso. Será que estou certo no MVC, ou errado? :roll:
E para responder isso não há dúvida que realmente é necessário ter um grande embasamento teórico e não um monte de código escrito.
O pessoal entendeu bem essa ideia e vem colaborando da melhor maneira possível expondo suas bases teóricas e também seus conhecimentos de anos, da melhor maneira possível.
O que mais me deixa feliz é que muitas pessoas com certeza estão tendo a oportunidade de esclarecerem suas dúvidas.

Ok rapaz? Agradeço muito por acreditar no trabalho que está sendo aqui mostrado.
Fico feliz por ter mostrado interesse pelo tópico, é uma honra!
Continue acompanhando conosco e não deixe de fazer suas perguntas se sentir necessidade.

Felicidades a todos os Gujeiros! Parabéns a todos. :wink:

Bom respondendo a dúvida da Ingrid, juntamente com as respostas do Sergio Taborda…

pelo que li, aqui, no post do taborda… no tal MVP (que li em outro canto ser uma variação do MVC, portanto não tem como deichar de ser um MVC)… voltando, no tal MVP a carcteristica principal é que a view e o modelo trabalham para o Presente …

Bom, se é este o caso, então realmente os exemplos que dei não são de MVP …

Eu simplismente desacoplo a VIEW e o MODEL … e uso o meu controler para ligar os 2 … view e modelo não se conhecem…

vou exemplificar com código (sim o código é de um exemplo web, mas é o que tenho pra mostrar…)

http://pastebin.com/FGJ296Ad (estou postando o código no paste bin, para não poluir o post)…

Vamos as explicações… esse é o código do meu controller, nele evito usar de lógica ao máximo… ele controla FLUXO, encaminha as coisas… a lógica já esta escrita, e não depende do controller… a view esta escrita, e não depende do controller nem do modelo… o trabalho do controller é traduzir a view para o modelo…

vamos ao exemplo…

Obs.: Antes de começar a ler… "logic" contém uma instancia de UsuarioLogic que é um objeto do modelo. "result" é um objeto do vraptor, que auxilia com os resultados para a view.


uri => /usuario/alterarSenha

@Post @TransactionScoped @Roles(includeResourceRoles=false) public void alterarSenha(Credential antiga,Credential nova) { if (logic.alterarSenha(antiga,nova)) result.redirectTo(this).meusDados(); else result.include("senhaInvalida", true); } Aqui eu recebo os dados da view, parte do trabalho de converter os dados da view em objetos é feito pelo VRaptor, afinal o VRaptor é parte do meu controle e me auxilia no modelo MVC para assim fazelo…

Na página web foi postados input texts normais, ele cai ai nesse método, no meu controller eu apenas uso a lógica para alterar a senha, se foi bem sucedida eu redireciono para meusDados, caso contrario eu continuo no mesmo caso, e apenas incluo no VIEW a mensagem de que a senha esta inválida.

uri => /usuario

@Get @Path("") public List<Usuario> listar() { return logic.listar(); }Aqui eu adiciono a view a lista de usuário, a listagem obviamente é feita na lógica, no controller eu só faço a chamada ao método (Obs, para o vraptor return list, é o mesmo que result.include(“usuarioList”,list) portanto nesse método do controller eu estou apenas colocando a lista que foi gerada na lógica dentro da view)

uri => /usuario/{id} , por exemplo /usuario/12

@Get @Path("/{id}") public void editar(Long id) { result.include("usuario", logic.buscar(id)); useForm(); }
aqui eu busco no modelo (através de uma lógica) o usuário do ID colocado na uri, e então adiciono ele a view, logo após eu carrego a página do formulário.

uri => /usuario/{id} , por exemplo /usuario/33

@Delete @Path("/{id}") @TransactionScoped public Usuario apagar(Long id) { Usuario result = logic.apagar(id); validator.onErrorUse(Results.logic()).redirectTo(getClass()).listar(); return result; }
Obs.: apesar da uri deste método ser a mesma do anterior, esse método é acessado quando a uri é usada através de um DELETE (isso são métodos http)
como podem ver a lógica de remoção esta no modelo, la dentro eu dou um apagar. em seguida vejo se houve erros de validação, em caso positivo eu redireciono para página de listagem.
caso a remoção seja um sucesso, eu apenas coloco na view o objeto que foi removido.

Enfim ai estão alguns exemplos, de como contruo meus controller… como podem ver a lógica não esta presente… apenas chamadas aos metodos corretos, e recuperação dos resultados e coloco esses resultados na view.

Bom, e se você olhar esta imagem que esta na WIKI PEDIA

e ler a legenda

“Model-View-Controller concept. Note: The solid line represents a direct association, the dashed an indirect association via an observer (for example).”

vai ver que é basicamente como uso… a ligação direta da VIEW com o MODELO é explicada, pq a view usava alguns objetos do MODELO, (normalmente objetos de informação, como entiades) para exibir informações…

Enfim é desta forma que uso…

para ajudar no exemplo, segue o objeto com lógica de verdade

Este objeto é o UsuarioLogic, que esta instanciado dentro de “logic” do controle, do exemplo dado no post anterior

[code]package br.com.simtecnologia.helpdesk.model.user;

import java.util.List;

import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.validator.Hibernate;
import br.com.caelum.vraptor.validator.ValidationMessage;
import br.com.simtecnologia.helpdesk.model.login.Credential;
import br.com.simtecnologia.helpdesk.model.queries.QueryUsuario;
import br.com.simtecnologia.persistence.DomainStore;

@Component
public class UsuarioLogic {
private final DomainStore helpdesk;
private final UsuarioSession usuarioSession;
private final Validator validator;
private final QueryUsuario query;
public UsuarioLogic(DomainStore helpdesk, UsuarioSession usuarioSession, Validator validator, QueryUsuario query) {
this.helpdesk = helpdesk;
this.usuarioSession = usuarioSession;
this.validator = validator;
this.query = query;
}

public Usuario buscar(Long id) {
	return helpdesk.get(Usuario.class, id);
}
/**
 * Altera a senha, de acordo com as credenciais, para o usuário logado, na sessão corrente.
 * @param credential as novas crendenciais contendo a nova senha.
 * @param nova 
 * @return 
 */
public boolean alterarSenha(Credential antiga, Credential nova) {
	if (!usuarioSession.isLogged())
		throw new IllegalStateException("Não há usuário logado para alteração da senha");
	if (!usuarioSession.confirmaSenha(antiga))
		return false;
	alterarSenha(nova,usuarioSession.getUsuario().getId());
	usuarioSession.getUsuario().setSenha(nova.getPassword());
	return true;
}
/**
 * Altera a senha para o usuário do <tt>id</tt> enviado.
 * @param credential as novas crendenciais contendo a nova senha.
 * @param id o ID do usuário o qual deseja-se alterar a senha.
 */
public void alterarSenha(Credential credential, Long id) {
	Usuario usuario = buscar(id);
	usuario.setSenha(credential.getPassword());
}

public List<Usuario> listar() {
	return helpdesk.list(Usuario.class);
}

public List<UsuarioRoles> listarRoles() {
	return UsuarioRoles.list();
}

public Usuario apagar(Long id) {
	if (usuarioSession.isLogged() && usuarioSession.getId().equals(id)) {
		validator.add(new ValidationMessage("Não é possivel apagar o seu proprio usuário", "id"));
		return null;
	}
	return helpdesk.remove(Usuario.class,id);
}

public Usuario atualizar(Usuario usuario) {
	validator.addAll(Hibernate.validate(usuario));
	return validator.hasErrors() ? null : helpdesk.marge(usuario);
	
}

public void adicionar(Usuario usuario) {
	validator.addAll(Hibernate.validate(usuario));
	if (!validator.hasErrors()) {
		if (query.hasUsuarioByLogin(usuario.getLogin())) {
			validator.add(new ValidationMessage(
					"já existe um usuário com o login " + usuario.getLogin(),
					"login"));
			return;
		}
		helpdesk.add(usuario);
	}
}

}
[/code]

Olá rapazes, desculpem pela demora. :frowning:

Sergio Taborda,

Pergunta1: Não é muito usado. Mas se for um sistema de chat como o exemplo que citou no último quote deste post, vai ser necessário senão o chat se manteria desatualizado na tela, certo?

Pergunta2: “O mecanismo que traduz o clique no botão para a chamada ao método no presenter está na visão.” Não entendi, desculpe. A visão não conhece o Presenter, certo? Então como ela vai chamar um método no Presenter?

Pergunta3: Talvez por não conhecer quase nada de JAVA WEB eu não entendi o que quis dizer nessa resposta.

[quote=sergiotaborda]Sim, o presenter é muito mais “controlador” que o controler do MVC. Infelizmente os nomes do MVC foram mal escolhidos ( deveria ser algo mais como Renderização-Componente-Dados)

Imagine um sistema de chat. Quando A envia uma mensagem a B ela chega pela camada abaixo do apresentação, ela chega pelo M do MVP. O M então precisa avisar o P que chegou uma mensagem para que o P faça algo com ela. Outro exemplo seria o sistema através do M avisar que a rede caiu e o P , sabendo isto, faz aparecer algum icon em algum lugar da V.
É por isso que o M pode ter que avisar o P. O P controla o estado de apresentação e a apresentação não depende apenas do que o usuário faz, depende tb do que o sistema faz e do que outros usuários fazem quando o sistema é multi-usuario. É por isso o MVP é mais natural para a camada de apresentação que o MVC. [/quote]

Lavieri,
Obrigada por mandar um exemplo quase pronto para me ajudar… :smiley: Gostei muito da explicação do mvp, mesmo sendo para WEB, dá para entender bem a idéia e tentar transformá-la em desktop.
Já havia escutado sobre VRaptor mas nunca usei. Eu estou elaborando um post mais técnico e específico para ver se alguém desafia responder essas minhas dúvidas que estão me deixando bem confusa em relação, agora, ao mvc. Estou entendendo bem a idéia que vocês estão mostrando mas sempre que observo um exemplo novo, mesmo sabendo que ele está lá para me ajudar, minhas dúvidas aumentam ainda mais… :cry: :?

Pedro Muyala,
Concordo com você quando fala sobre ‘embasamento teórico’ mas um pouco de código também ajuda a entender, não acha? Até mesmo algumas de suas postagens anteriores (lá nas páginas 9, 10) alguns amigos explicavam como montar o mvc através de códigos mesmo… chegou a falar até de exception’s se não me engano. Na verdade as minhas dúvidas são bem técnicas, mesmo eu me apreendendo em um exemplo simples, como o de uma agenda. E concordo quando diz que um pattern deveria ser de um Único Entendimento. Na próxima postagem vou fazer perguntas mais específicas e separadas por números para que as respostas fiquem bem definida para aquela pergunta e não para um todo. espero também estar ajudando assim no seu tópico.

Obrigada a todos meninos! :smiley: Estou muito feliz por todos. :wink:

Olá rapazes, eu novamente com as perguntas que comentei elaborar. :smiley:

O que realmente está difícil de entender é porque as implementações (tanto MVC quanto MVP) não seguem o desenho da arquitetura?
Nessa postagem vou focar no mvc.

Veja:



Olhando as imagens acima que mostram o formato da arquitetura MVC entendi que no desenvolvimento Desktop com Swing:

Ponto1: Cada letra do mvc é um pacote ‘package’.
Ponto2: O mvc trabalha dentro da camada e não ‘jampeando’ camadas.
Ponto3: Seu uso é melhor empregado na camada de cliente e na camada de apresentação.
Ponto4: O modelo é quem envia/recebe dados da camada inferior ( a de baixo ) quando necessário.
Ponto5: O modelo é o lugar onde as coisas acontecerão de verdade. As funcionalidades estão nele. Pode ser uma única classe ou ‘n’ classes.
Ponto6: O modelo ‘só e somente’ notifica a visão de alterações em seu estado através do pattern observer ( ou outra forma de associação indireta ).
Ponto7: O modelo não conhece o objeto do controlador que está alterando seu estado. E só conhece o objeto da visão ( o listener implementado por ela ) através do pattern observer, pois esse objeto se registra no modelo como ouvinte dos eventos de notificação gerados por ele próprio.
Ponto8: O controle é quem define o comportamento dos ‘eventos’ que chegam da visão para realizar mudanças de estado no modelo.
Ponto9: O controle conhece o objeto modelo e o objeto visão.
Ponto10: O controle altera o modelo chamando seus métodos diretamente ( ou outra forma de associação direta ).
Ponto11: O controle seleciona outra visão a ser exibida se em uma determinada situação que ocorrer tornar-se necessário.
Ponto12: A visão é quem interage com o usuário.
Ponto13: A visão só conhece o objeto do controle ( o listener implementado por ele ) através do pattern observer, pois esse objeto se registra na visão como ouvinte dos eventos gerados por ela própria.
Ponto14: A visão ‘só e somente’ manda um user gesture para o controlador através do pattern observer ( ou outra forma de associação indireta ).
Ponto15: A visão conhece o objeto modelo e o consulta para se reenderizar chamando seus métodos diretamente ( ou outra forma de associação direta ).

Se esses 15 pontos estiverem corretos exitem algumas dúvidas por trás dessas imagens que não são esclarecidas e são elas:

Dúvida1: Se o main ou um outro objeto cria as instancias da visão, controle e modelo, como um irá conhecer o outro? Serão passados por referência? Ex:

 public class AgendaVisao implements iAgendaVisao { } 
 public class AgendaControle implements iAgendaControle { } 
public class Agenda {
   public static void main(String args[]) {
      AgendaModelo m = new AgendaModelo();
      AgendaVisao v = new AgendaVisao(m);
      AgendaControle c = new AgendaControle(v,m);

      m.addModeloListener(v);
      v.addVisaoListener(c);
   }
}

Dúvida2: Como o controle seleciona uma nova visão? Ele vai instanciar uma nova visão, um novo modelo, ou seja, vai fazer o papel que está fazendo o main acima ( do código )?
Dúvida3: Em nenhum momento o controle chama métodos para ‘puxar’ dados da visão para ele. Ou seja, ele não deverá fazer isso, certo? Ele não foi criado para isso.
Dúvida4: Se é verdade as dúvidas 4 e 5 então o mvc não foi criado para formulários/entrada de dados, sendo esse problema corrigido com o padrão mvp?
Dúvida5: Quando eu clico em um JButton que está sendo exibido na visão, na verdade, eu estou interagindo com um controlador (o JButton) que lança um evento chamado ‘user gesture’, correto? O mesmo valeria se eu clicasse em um JComboBox, saisse de um JTextField, entre outros componentes do swing, certo?

Dúvida 6 e trivial: Na verdade, olhando as imagens que tentam mostrar a arquitetura mvc você tem esses 15 pontos que citou acima, porém o que ocorre de fato é uma interação do usuário com o controle. Seu main chama um controle e ele definirá qual visão será exibida e qual modelo usar naquele momento. É ele também quem faz a ligação entre a visão e o seu modelo com o observer. Na verdade, a visão recebe o ActionListener do controle e instala (coloca ele para ouvir) os eventos de determinados botões na visão, que não passam de controladores. Seria como o exemplo citado pelo Lavieri na página 14 só que entrada de dados nos controladores exibidos na visão (ex: JTextField) não podem ser lidos pelo controle nem passados pelo evento. É isso :?:

E lembrem-se: é somente uma simples agenda em desktop. Percebam que não uso absolutamente ferramenta nenhuma a não ser um Bloco de Notas (é isso mesmo, NOTEPAD) e as linhas de comando java e javac. Tenho certeza que vão ler isso e me indicarem muitas ferramentas… mas não quero no momento. quero aprender bem o básico e simples.

Obrigada meninos pela paciência, por toda a ajuda que postam, leio elas com muito carinho e faço o possível e impossível para enteder tudo. :smiley:
Desculpem minha dificuldade faz pouco tempo que comecei a estudar Java (não tem um ano e meio)… Vou aguardar pelas respostas.
Gostei do sistema de resposta que o Sergio Taborda adotou, respondendo item por item no assunto de mvp em alguns posts anteriores, ficou bem didático.
Até +…

não terminei de ler, então vou respondendo logo um ponto onde discordo (teoricamente do que disse) …

O modelo não conhece a view, o modelo não conhece o Listener implementado por ela, através do pattern Observer…

O modelo na verdade define uma Interface para quem quiser Ouvilo, ou seja uma interfacepara seu Listener … quem quer que implemente a interface não será conhecido pelo modelo… ela apenas checa a lista de objetos que se registraram como listener… todos esses objetos para o modelo são apenas as interfaces que ele definiu, então ele usa o método definido na interface (que é parte do modelo) … e ai que alguem recebe a informação…

Portanto o modelo não conhece ninguem neste ponto… nem a view, nem o controller…

Falando de implementação eu custumo implementar o listener no Controller (para deixar view mais solta) … o controle recebe as notificações e ele avisa a view sobre a alteração… assim tanto a view como o modelo ficam mais livres…

se vc implementa na view a interface Listener do modelo, estará mais acoplada ao modelo… fazendo isso no controle fica mais solto ao modelo…

Como o controller já é ligado ao modelo e a view, então não há problemas de acoplamento

Edit:
Aquela linha indireta onde há a seta MODELO —> VIEW é pq o modelo indiretamente pode passar informações diretamente a view… mas isso ele faz sem conhcer a view, ele só conhece o proprio modelo… a Interface Listener é parte do modelo, portanto ele não conhece a view, e é por isso que é dito que a informação é passada indiretamente…

Edit2:

aqui vale o mesmo raciocinio acima… a view não conhece o controle neste … isso é indireto, a view conhece é a interface do Listener que faz Parte da view, quem a implementa e se registra nela, não é conhecimento da view, é algo feito com desacoplamento total…

Não, o controle não define… isso… isso já esta definido… o controle só faz acontecer…

Por exemplo… se a view em um botão SALAR, e nele esta o FOMRULÁRIO de USUARIO, ao clicar em SALVAR, o controller não define o comportamente do evento… ele apenas conhece a view suficientemente, para conhecer a ROTA o destino, o que deve acontecer…

Ele então, ao acontecer o clique no botão… pega os dados do formulário, e envia lá para baixo, para o modelo salvar… o modelo salva, e ele ratorna informando que tudo ocorreu bem… e por exemplo dando um disable no botão de salvar…

O trabalho do controle é este… a view existe pra fazer algo … mas a view não sabe quem pode faze-lo
O modelo é quem faz as cosias … e esta apenas esperando por ordens…

o controle sabe o que a view quer fazer, algo, e sabe que parte do modelo é capaz de fazer… então ao ver que um evento aconteceu na view, ele faz o evento passar da view para a parte correta no modelo, fazendo aquilo acontecer…

Não necessariamente… vc pode ter uma estrutura de pacotes mais complexa, mas pode ser assim tb.

[quote=ingridfarabulini]Dúvida1: Se o main ou um outro objeto cria as instancias da visão, controle e modelo, como um irá conhecer o outro? Serão passados por referência? Ex:

 public class AgendaVisao implements iAgendaVisao { } 
 public class AgendaControle implements iAgendaControle { } 
public class Agenda {
   public static void main(String args[]) {
      AgendaModelo m = new AgendaModelo();
      AgendaVisao v = new AgendaVisao(m);
      AgendaControle c = new AgendaControle(v,m);

      m.addModeloListener(v);
      v.addVisaoListener(c);
   }
}

[/quote]
uma forma melhor de fazer isso é

public static void main(String args[]) { new AgendaController().start(); }

[code]
public class AgendaController {
private AgendaModel agendaModel;
private AgendaView agendaView;

public void start() {
     agendaModel= new AgendaModel();
     agendaView= new AgendaView(agendaModel); //isso não é bom <== estou apenas exemplificando
     agendaView.exibir();
}

}[/code]

Exemplifiquei acima, conforme o modelo que vc apresentou, abaixo vou colocar uma forma que acredito ser melhor

quando falo que akilo não é bom… é pq o ideal é que seja assim como esta abaixo

[code]
public class AgendaController implements SalvarListener, ListarListener, ExcluirListener etcListener {
//acima coloquei vários listener, apenas para efeito didatico, para deichar tudo em um único controle

private AgendaLogic agendaLogic; //agenda lógic é parte do modelo
private AgendaView agendaView;

public void start() {
     agendaLogic = new AgendaLogic();
     agendaView= new AgendaView();
     agendaView.exibir();
}

//evento escutando salvarListener
public void salvarListener(EventoSalvar eventoSalvar) {
    Pessoa pessoa = eventoSalvar.getPessoa(); //aqui eu pego a pessoa populada a partir do evento salvar
    //o agenda view poderia ser resgatado através de algo como eventoSalvar.getSource();
    agendaLogic.salvar(pessoa);
    agendaView.getBotaoSalvar().setEnable(false);
    agendaView.showMessage("Pessoa salva com sucesso");
    //vc pode mudar de tela ou fazer outras coisas...
}

public void excluirListener(EventoExcluir eventoExcluir) {
    agendaLogic.excluir(eventoExcluir.getPessoa());
   //... etc
}

}[/code]

enfim… essa é a minha forma de fazer

[quote=ingridfarabulini]Dúvida2: Como o controle seleciona uma nova visão? Ele vai instanciar uma nova visão, um novo modelo, ou seja, vai fazer o papel que está fazendo o main acima ( do código )?
[/quote]
uma forma de fazer ?

new ControleDeOutraView().start(); this.finish();

outra forma de fazer ???

controlePrincipal.startView2(); //ou seja, todo controle tem uma referencia ao controle principal, que sabe como iniciar o controle de cada view this.finish();

vai puxar sim… como no exemplo que coloquei mais a cima… ele puxa informações da view, e repassa para o modelo… a VIEW não deve alterar o estado do modelo… isso é trabalho do controlle … (da ate pra alterar, mas ai tem q ser por meio indireto com observers… e nesse caso o resposável por registrar os observers é o controle)

não vou entrar no merito do MVC ou MVP, não li muito sobre MVP … mas continuo afirmando que a resposta é que o MVC foi sim criado pra isso também…
o Controller é quem altera o estdo do modelo… e o controle tem ligações de forma solida tanto com a view com com o modelo… portanto ele pode sim pegar as informações da VIEW e repassar ao modelo…

vc esta interagindo com a view… a view pode ter milhoes de respostas para as suas ações… por exemplo… dar FOCO pode siginificar alterar a cor do contorno do field para vermelho… isso é a view quem faz…

o Controller pode é registrar observers para ouvir ações do usuário e assim também responder a esses eventos… mas ele só consegue responder aos eventos pq a VIEW esta interagindo… é a view quem dispara a varrer todos os listener e enviar os eventos para quem escuta… portanto a interação é com a view

Como falei acima, não é o controle quem define as coisas… o controle apenas faz a “implementação” ele … conhece o modelo e a view, portanto o controle fazo meio de campo… as interações com a view são com a view… toda interação com a VIEW gera um evento… o controle pode capturar o evento, e fazer ele ir para no modelo, pegar infos do modelo e colocar nos lugares corretos da view…

vc inicia o programa com new ControllerX.start(); apenas por comodidade… isso não quer dizer que o programa é o controle apenas é mais facil assim…

[quote=ingridfarabulini]
Pedro Muyala,
Concordo com você quando fala sobre ‘embasamento teórico’ mas um pouco de código também ajuda a entender, não acha? Até mesmo algumas de suas postagens anteriores (lá nas páginas 9, 10) alguns amigos explicavam como montar o mvc através de códigos mesmo… chegou a falar até de exception’s se não me engano. Na verdade as minhas dúvidas são bem técnicas, mesmo eu me apreendendo em um exemplo simples, como o de uma agenda. E concordo quando diz que um pattern deveria ser de um Único Entendimento. Na próxima postagem vou fazer perguntas mais específicas e separadas por números para que as respostas fiquem bem definida para aquela pergunta e não para um todo. espero também estar ajudando assim no seu tópico.

Obrigada a todos meninos! :smiley: Estou muito feliz por todos. ;)[/quote]

Olá Ingrid, tudo certo?

Sim com certeza o uso de código-exemplo ajuda. Na verdade, como você mesma alega, é melhor aprender o básico. O básico, na minha humilde opinião, é teorico. Entendendo bem as complexidades teoricas aí sim poderá designar do seu tempo para sustentar a parte de codificação. Desculpa se me expressei mal, não quis izer que não era para postar código, longe disso, quem sou eu para dizer isso. :oops:

:arrow: Mas olha depois dessa explicação acima do gujman lavieri (por sinal, a senhora faz perguntas muito inteligentes, até parei de perguntar um pouco para não quebrar seu raciocínio) ao meu ver o difícil agora é não conseguir entender… ficou muito visível e perceptível o funcionamento de um MVC, se bem que é aquilo que comentou anteriormente que olhando para a figura e olhando para a forma de implementar tá tudo diferente… nunca iria imagina que na verdade a seta tarcejada que vai do model para a view significava outra coisa! Nunca imaginaria que os eventos de notificação podem ser descarregados no controle… Acho que ninguém mais vai discordar dessa explicação acima não enxergo outra forma de fazer.

Enfim só posso agradecer aos dois pelo bom andamento do tópico e obviamente a todos os demais que vieram colaborando. :slight_smile:
Se tiver dúvidas, sugestões, opiniões diferentes, visões diferentes ou críticas, por favor não deixe de postar! Só assim podemos nos ajudar. :wink:
[size=14]SUCESSO A TODOS! Continuem conosco.[/size]

pedromuyala, desculpe me intrometer no seu tópico, mas estava pesquisando sobre MVC e acabei achando esse tópico que por sinal esclareceu muitas coisas. Ainda tenho algumas dúvidas e gostaria que colocá-las aqui.

  1. Se entendi direito, o MVC é aplicado a uma camada só, geralmente a camada de apresentação, é isso mesmo? E no caso do MVP, seria a mesma coisa?
  2. Nesse caso, os modelos que eu estaria lidando só estariam relacionados a essa camada de apresentação, como um tableModel por exemplo?
  3. No caso de uma aplicação desktop com swing, ele já implementa o MVC? O que eu teria que implementar nesse caso? Como faria a interação MVC dentro da apresentação?
  4. Se eu precisasse persistir os dados de um form de cadastro, quem faria a conversão do modelo da apresentação para o modelo de domínio? Seria o presenter do MVP (caso use MVP)?
  5. Seria a mesma coisa no caso de eu precisar obter os dados de um banco de dados e exibí-los em um JTable?

Me desculpem se o que estou perguntando é muito óbvio. Eu achava que entendia o MVC, mas lendo esse tópico e alguns artigos a respeito vejo que a coisa é um pouco diferente.
Parabéns pedromuyala pela iniciativa, esse tópico já me esclareceu muita coisa. :wink:

Abraços, Raphael.