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

heheh eu ia procurar essa thread agora… não estou respondendo o colega acima, mas gostaria de complementar um pouco as informações que coloquei mais acima…

Os tais beans de informações que falei, que transitam entre todas as camadas e que fazem parte do modelo, eles podem ser melhor representado pelo Modelo de Dominio…

segue uma ilustração que demonstra como o Domain Model tem passe livre por todas as camadas…

desta imagem vale lembrar que:

  • Business Layer e Data Access Layer fazem parte do Modelo, e apenas do modelo…
  • Presentation Layer faz parte da View
  • O Controller se localiza entra a Presentation e a Business Layer, mediando os 2, para que elas sejam fracamente acopladas…

Obs.: apeas do caminho mostrado na ilustração ser do cliente passando informações para o modelo, essas ligações entre as camadas são vias de mão dupla, e o Domain Model, tranzita entre as camadas, tanto indo em direção ao database, como ao cliente…

Portanto, os beans ou entidades que tranzitam com informações fazem parte do “Domain Model”, e apesar de pertencer ao M do MVC, tem tranzito livre entre as camadas…

Em alguns casos em projetos modulados o Domain Model pode ser separado em um jar… e no minimo, para uma boa organização, o Model deve ser separado em um pacote… segue um exemplo de um projeto meu…

Boa tarde companheiros gujeiros, é feriado!

Intormeter? Que é isso! O tópico está aqui para isso mesmo. O que eu tenho da minha parte a dizer é desejar os PARABÉNS por estar participando.
Suas perguntas são identicas a de muitas pessoas e devem ser respondidas. Eu sempre estou pedindo para os companheiros postarem suas dúvidas, perguntas, críticas, sugestões… sempre!
E para manter a qualidade, vou fazer um “quote” para cada pergunta.

Não. O modelo MVC (assim como o MVP, uma variante do MVC) pode ser aplicado dentro de qualquer uma das camadas que tiver. Lógico, por força maior, ele será implementado “na maioria das vezes” nas camadas que interagem com o usuário. Ex: Cliente e Apresentação. Vale sempre lembrar que o MVC não faz “jamper” entre camadas, ele não está ligando camadas uma a outra.

TableModel é um modelo que faz parte dos componentes do Java Swing. Quando você cria um objeto JTable você está criando uma instancia do controlador JTable, ou seja, JTable é um controlador. Sua visão e seu modelo são imediatamente criados também. Dentro da sua camada de apresentação esses três objetos estarão presentes (MVC). Quando você clica em um campo da visão do JTable, na verdade, o que ocorre é uma interação do usuário com o controlador JTable. Esse, por sua vez e se necessário, lança um evento para quem quiser ouvir (podendo ser um outro controlador). Você poderá criar outros objetos que farão parte da camada de apresentação. Vale lembrar que, para existir alta coesão e baixo acoplamento, legal seria esses objetos trabalharem apenas na sua camada de origem, sendo que para se comunicar com camadas inferiores ocorre-se uma tradução. (Vai entender melhor vendo este link.)

Na verdade, os componentes swing JFrame, JPanel, JTextField, JButton, etc. são controladores. Quando você vê na tela uma janela aberta, o que está enxergando é a visão do componente. O modelo também está lá presente aguardando que algo seja consultado ou modificado. A visão exibe os dados presentes no modelo naquele momento, estando apta a se reenderizar sempre que o respectivo modelo for alterado. Quem está mediando essas partes é o controlador, como explicado nas postagens do Lavieri acima. Isso tudo está na VISÃO! Mas, espera aí, eu perguntei em uma aplicação? Como faria a interação MVC dentro da apresentação?

Veja a imagem abaixo:

Tudo isso acima está na Camada de Apresentação. Lembre-se: Camadas são abstratas. No Swing, o main é um controlador (não aparece na imagem). Ele cria o objeto controlador da sua aplicação(Ex: JCadastro.). JCadastro cria um objeto de JFrame (controlador instanciou outro controlador). JFrame cria um objeto de JPanel (novamente controlador instanciando outro controlador). JPanel cria um objeto de JTable, mantendo a lógica. Repare que cada controlador (JFrame, JPanel,…) instancia seu respectivo Modelo e Visão (até JCadastro) e que cada controlador pode lançar um evento externo. Quando o usuário pressiona uma tecla em uma célula da JTable quem está recebendo o evento de “tecla x pressionada” não é a visão, mas sim o controlador JTable. O controlador vai encaminhar essa informação para o modelo que vai se atualizar e fazer com que a visão se reenderize e exiba a tecla x pressionada dentro da célula. Repare que, ele realizou toda a sua função prevista dentro da visão da sua camada de apresentação, o que responde a sua pergunta. Mas quem gerou o evento de “tecla x pressionada”? Foi algum objeto controlador responsável pelo teclado.

Agora vem o detalhe importante, que fará as coisas terem sentido. Observe a imagem e localize o JTable em azul. Perceba que NÃO está sendo mostrado na imagem o evento que o modelo lança para a visão (que na verdade é intermediado pelo controle, segundo Lavieri nos posts acima) sempre que necessário realizar uma reenderização. MAS é mostrado em um círculo os eventos que são de comunicação externa, ou seja, com o outro controlador. Entenda: Assim como o objeto controlador de teclado gerou e lançou um evento para o JTable, o JTable vai gerar e lançar um evento para o controlador da Camada de Apresentação (que vai estar escutando a visão e esperando por eventos gerados nela).

Sim. No caso de usar o MVP.

Sim. Para esclarecer mais dúvidas das duas situaçãoes, recomendo este link aqui.

E PELO AMOR DE DEUS não sei se o que respondi está correto. Eu venho estudando este tópico quase que diariamente, procuro fontes na Internet, no meu dia-a-dia… tudo que respondo é baseado naquilo que estou entendendo, ou seja, pode muito provavelmente ter inúmeros erros! E peço por favor para todos que prestem muita atenção na minha respostas e me alertem de erros porque senão acabo prejudicando muitos companheiros no lugar de estar ajudando.

Muito obrigado mais uma vez pela postagem, espero que não abandone o tópico. Um abraço. :wink:

Olá Lavieri, tudo bom? Obrigado rapaz por estar ajudando aqui com o tópico.

Lendo isso preciso perguntar porque se for real vai derrubar alguns dos conceitos que aprendi aqui mesmo neste tópico: Percebi que você distribui o MVC pelas camadas, melhor dizendo, “jampeou” as camadas, isso é correto? :shock:

Assim eu até este momento entendia que o MVC era aplicado na camada, assim:

  • §resentation Layer (onde está presente o MVC);
  • (B)usiness Layer;
  • (D)ata Access Layer;

Para P se comunicar com B, o objeto do modelo em P chama o método necessário do objeto da visão presente em B.
Para B se comunicar com D, o objeto do modelo em B chama o método necessário do objeto da visão presente em D.
Para D se comunicar com B, o objeto do modelo em D chama o método necessário do objeto da visão presente em B.
Para B se comunicar com P, o objeto do modelo em B chama o método necessário do objeto da visão presente em P.
Isso é o que eu sei. Não sei se existe algum padrão para comunicação entre camadas (andares) mais eficiente, isso era uma das minhas próximas perguntas. :?
Mas uma certeza que tinha até este momento é que o MVC != Camadas, segundo PCalcado no Fragmental e Sergio Taborda e até mesmo você!

Outra coisa que não entendi é esse “Domain Model” isolado e utilizável para todas as camadas.
Por favor Lavieri, peço que me explique onde estou errando, se for possível, claro?

[size=14]E pessoal não se envergonhem de fazer as perguntas, críticas, sugestões, opiniões contrárias… Tudo vai colaborar a todos os companheiros!
Mais uma vez obrigado a todos da administração do GUJ e seus moderadores pela oportunidade.
Ficarei no aguardo por respostas![/size] :wink:

Já li isso do MVC dentro de uma camada, no blog do sergio taborda, eu discordo, e vc pode encontrar isso em N bibliografias, q ainda vou discordar, até alguem me dar um motivo válido…

O Swing é feito com MVC, mas isso não quer dizer que MVC = VIEW … mvc é para separação dos seus componentes…

por exemplo, veja esse texto retirado do Wikipidia http://pt.wikipedia.org/wiki/MVC

Portanto na minha opinião, e na retirada deste texto, MVC e camadas não tem nada a ver um com outro… tanto que quando falei do MVC, o M (Model) agrupa 2 camadas, “businnes” e “persistence”, o Domain Model é criado dentro do business, faz parte dele, mas transita dentro de todas as camadas.

A camada de persistence não aparece na imagem dos meus pacotes que coloquei aqui como exemplo, elas não aparecem pq minha camada de persistencia fica em um .jar do meu projeto, mas também é uma camada bem definida e separada…

Bom, vc já trabalhou com Hiberante ou outro domain store ? se já fica bem fácil de entender, se não vou tentar explicar…

Em seu projeto sempre existem objetos de dominio, que contem informações, esses objetos são os que são persistidos, como são persistidos tem que descer até a camada de persistencia, eles precisam ser recuperados, e processados na camada de negocio, a camada de apresentação precisa exibir suas informações portanto eles vão até la também…

Vamos a um exemplo pratico…

package br.com.guj.livraria.domain; //objeto de dominio public class Livro { private String nome; private double preco; private Categorai categoria; public String getNome(){...} public void setNome(String nome){...} public double getPreco(){...} public void setPreco(double preco){...} public Categoria getCategoria(){...} public void setCategoria(Categoria categoria){...} }

Conciderando o que falei… Model engobla o dominio (ou seja esse livro) o businees (as regras de negocio) e o persistence (ou seja a cama de persistencia)…

pckage br.com.guj.livraria.business; //regra de negocio public class AcervoService { private DomainStore livraria; //esse vem da camada de persistencia private Queries queries; //esse vem da camada de negocio mas faz buscas na camada de persistencia private Validador validador; //esse é da propria camada de negocio public void addLivro(Livro livro) { if (validador.valido(livro)); livraria.add(livro); } public void devolverLivro(Livro livro) { Emprestimo emprestimo = queries.forEmprestimo().ultimoByLivro(livro); emprestimo.setDevolvido(true); emprestimo.setDataDevolucao(new Date()); livraria.merge(empretimo); //merge é o mesmo que atualizar } public boolean emprestarLivro(Livro livro,Pessoa pessoa) { Emprestimo emprestimo = queries.forEmprestimo().ultimoByLivro(livro); if (emprestmo != null) //caso o livro esteja emprestado não pode emprestar return false; emprestimo = new Emprestimo(livro,pessoa); livraria.merge(empretimo); return true; } }

bom a partir daqui temos que a camada de persistencia pode conhecer ou não a camada de negocio (business), depende do seu nivel de abstração, usando Hibernate por exemplo, a camada de negocio nem precisa conhecer a de negocio…

a camada de negocio definitivamente não conehce a VIEW, nem um eventual CONTROLE, necessário para acoplar a view a camada de negocio… assim nela não há códigos para view nessa camda…

o camda “view” quer por exemplo exibir um livro, para fazer isso, ela usa um objeto de DOMINIO, o objeto “Livro” esse é o objeto que tranzita entre todas as camadas, as vezes é possivel adaptar um objeto para a view não ter q manipular direamente um objeto de dominio, mas geralmente não se faz isso…

em um dado momento, escolhido o livro, o usuário quer tomar ele emprestado… nesse momento ao clicar no botão “EMPRESTAR” da view, o objeto de negocio AcervoService deve ser ativado, usando-se o método emprestarLivro(livro,pesso) … a view não precisa conhecer as regras de negocio, então no MVC controi-se um controle para mediar essa chamada… então

View no controle

[code]pckage br.com.guj.livraria.controll; //controle para se ligar com uma view JSP

public AcervoController {
//…
public void emprestarLivro() { //aki exitem mil maneira de recuperar os objetos da view
//vou mostar uma da web.
String idString = (String)request.getAttribute(“livro.id”); //essa string vem em um post de um form.
Integer id = Integer.valueOf(id);
Livro livro = acervoService.buscarLivro(id);
Usuario usuario = (Usuario)session.getAttribute(“usuario”); //um usuário logado na sessão
Pessoa pessoa = usuario.getPessoa();
request.setAttribute(“livro”,livro); //colocando o livro para pode ser exibido em uma página por exemplo
if (acervoService.emprestarLivro(livro,pessoa));
response.sendRedirect("/pagianDeSucesso.jsp");
else
response.sendRedirect("/pagianDeFracasso.jsp");
}
//…
}[/code]

bom la na view vc também vai usar o objeto livro para exibir as informações do livro que foi emprestado…

enfim… espero ter ajudado…

Obrigado pedromuyala, pela atenção. Acho que agora estou sacando melhor a coisa.

[quote=pedromuyala]
Não. O modelo MVC (assim como o MVP, uma variante do MVC) pode ser aplicado dentro de qualquer uma das camadas que tiver. Lógico, por força maior, ele será implementado “na maioria das vezes” nas camadas que interagem com o usuário. Ex: Cliente e Apresentação. Vale sempre lembrar que o MVC não faz “jamper” entre camadas, ele não está ligando camadas uma a outra. [/quote]

Me desculpa, não perguntei direito. Eu perguntei exatamente se o MVC não fazia essa ligação entre as camadas, mas já entendi. Eu estava chegando a essa mesma conclusão, mas lendo o post do Lavieri acima e vendo algumas definições na internet, estou mudando um pouco de opinião. Conforme aquele link falando sobre a evolução do MVC:

Essa é opinião de um ignorante no assunto, mas pelo que eu entendi, a idéia inicial do mvc era a de ligar justamente a parte de visualização com a parte de negócios. Você pode ser mais específico e aplicar a idéia na camada de apresentação como o swing faz, ou você pode considerar isso a um nível mais abstrato e implementar isso nas camadas como um todo. Well, it’s only my two cents!

Fala Lavieri, boa tarde! :slight_smile:

Eu sei que não citou isso, mas pode ter certeza que confio claramente no que está afirmando. Tanto é verdade que estou perguntando sobre seus exemplos porque estou confiando cegamente naquilo que está afirmando. E digo mais: Das quinze páginas postadas que acompanho durante a quase um ano você está sendo a pessoa esclarecedora sobre o assunto, transformando a explicação técnica de forma popular, legível, exemplificada, lê as postagens e entende muito bem as perguntas antes de responder e quando responde se arma de argumentos fortes para não restarem dúvidas. Não que esteja desmerecendo o bom trabalho de todos os companheiros que por sinal já ajudaram e muito. :-o

Exatamente o que pretendia fazer. Após definir o MVC na Camada (o que já não estou acreditando mais, como você mesmo diz, que me apresentem algo válido do porque não trabalhar na forma que mostrou acima) minha principal próxima questão seria: Como as camadas interagem uma com a outra, sendo que, por exemplo, a Apresentação usa MVC mas a Camada de Negócios não usa, como elas se falariam, então? :roll: :roll: :roll:

Mas você já esclareceu na sua última postagem acima. :stuck_out_tongue: Está mais do que claro, só posso agradecer por ter exposto sua idéia aqui. É isso que peço a todos os companheiros que mostrem sua forma de pensar sobre o MVC mesmo que sejam interpretações diferentes. Esse assunto que muitas vezes é mal explicado tem que ficar claro para todos. Esse é o objetivo das três letrinhas.

Lavieri, parabéns. Espero que continue aqui conosco sempre atento e sempre que puder acrescentar, por favor, não se acanhe, poste.
Um abração companheiro, mais uma vez muito obrigado pela colaboração. Sucesso. :wink:

O que é isto, span no GUJ, não, por favor não.

@pedromuyala

é o seguinte… MVC é uma separação de componentes, vc pode muito bem aplica-lo a uma única camada, afinal toda camda tem sua VIEW (a interface que ela expoem para as outras camadas usarem) tem seu modelo de negocio, ou seja a implementação real, o como ela funciona… tem objetos de dominio, ou seja informações que ela passa para fora da camada a través de suas interfaces… e em projetos maiores, vc pode precisar de um controle, isso serve mais quando vc tiver mais de uma implementação…

Quer um exemplo de onde isso ocorre ?

javax.persistence.*;

o JPA, Java Persistence API é a view do especificação, ela é bem difinida, é nela há todas as interfaces usadas quando vc trabalha com a API…

O Hiberante ja tinha um objeto que fazia tudo que esta API queria… então, o Hiberante criou um adaptador para ligar as regras de Negocio dele (ou seja um Session do hiberante) a view do JPA…

sendo assim, vc pode dizer que nesse caso…

VIEW = a especificação JPA MODEL = a session do Hiberante CONTROLLER = o adaptador, que transforma uma requisição do JPA em uma requisição que a Session entende.

Enfim a view é escrita sem se importar com a implementação
o Modelo foi escrito antes mesmo dessa view existir (Session do hiberante veio antes da especificação do JPA)
o Controller foi feito para mediar, essas duas partes que não precisam se conhecer.

neste caso é um uso meio ao contrario do MVC hehehe… afinal vc tem 1 VIEW o JPA e tem várias dominios que usam essa mesma view… há varias implementações desta especificação, TopLink, OpenJPA…

Enfim MVC é a forma que vc vai organizar as coisas, ele se preucupa principalmente com a separação de responsabilidade e com o baixo acoplamento.

Se vc não conhce hiberante ou jpa e não entendeu o exemplo que dei, não fique triste, um dia vc vai acabar usando Hibernate ou Jpa ^^

Obs.: Não estou aqui afirmando com 100% de certeza, as implementações de JPA usam MVC! … não é isso … o que estou falando é que a forma que hiberante implementa a especificação se aproxima bastante do MVC…

Putz Spam denovo é de doer o coração hein! Lembro que no começo também ocorreu algo relacionado a SPAM! Lá nas primeiras postagens. :shock:
Mas se for, entenda bem, SE FOR para ajudar aí o pessoal a continuar mantendo o GUJ lindo do jeito que está… pode colocar mais kkkkkk… :stuck_out_tongue:

Opa Lavieri, beleza homem?
Mais uma vez obrigadão por toda atenção e tempo que está desprendendo em ajudar cara, parabéns mesmo.
A cada postagem sua a coisa vai ficando cada vez mais transparente e até mesmo fácil. :-o

E pelo que parece os companheiros Gujeiros também estão de pleno acordo com seu fundamento cara, até o momento está sendo bem aceito, reparou?
A sua idéia até agora é a única que não foi rebatida por ninguém, o que é um ótimo sinal, é finalmente o entendimento geral que procuro nas pessoas.
Todos devem conhecer o padrão da mesma forma, esse é o objetivo.

Vou ler e entender sua última postagem com calma volto para responder, caso haja dúvida.
Felicidades, volto a postar o mais breve possível! :wink:

Olá meninos, já cheguei! :smiley:

Desculpem não ter escrito antes mas aproveitei esses dias para ler todos as postagens desde o início da conversa e tentar ao menos mostrar algum resultado.
Bom tentei seguir os conselhos da galera. Para usar o Observer, segui o link que o André Fonseca postou. Não coloquei exception até este momento, como indicou o Bruno Laturner. A estrutura do controle segui as explicações do Lavieri. Também não implementei as validações até mesmo porque fiquei com algumas perguntas em aberto, antes de continuar, preciso esclarecê-las.

Vamos ao código:

Inicialização:

    public class AgendaIngrid {
   		
       public static void main(String args[]) {
         new AgendaControle();
      }
   }

Visão:

   import javax.swing.*;
   import java.awt.event.*;

    public class AgendaView extends JFrame {
     
      private JTextField nome, eMail, telefone;
      private JButton bCadastrar;
       
       public AgendaView() {
         JPanel p = new JPanel();
         p.add(new JLabel("Nome:"));
         p.add(nome = new JTextField(10));
         p.add(new JLabel(" - Telefone:"));
         p.add(telefone = new JTextField(10));
         p.add(new JLabel(" - E-Mail:"));
         p.add(eMail = new JTextField(10));
         p.add(bCadastrar = new JButton("Cadastrar Pessoa >>"));
         add(p);
         setTitle("Agenda Ingrid vs1.0");
         setSize(720,70);
         setResizable(false);
         setDefaultCloseOperation(EXIT_ON_CLOSE);
         setVisible(true);
      }
   
       public void setPessoa(AgendaBean ab) {
         this.setNome(ab.getNome());
         this.setTelefone(ab.getTelefone());
         this.setEMail(ab.getEMail());
      }
   	
       public AgendaBean getPessoa() {
         AgendaBean ab = new AgendaBean();
         ab.setNome(this.nome.getText());
         ab.setTelefone(this.getTelefone());
         ab.setEMail(this.getEMail());
         return ab;
      }
   	
       public void addBotaoCadastrar(ActionListener al) {
         bCadastrar.addActionListener(al);
      }
   	   	
       public void setNome(String nome) {
         this.nome.setText(nome);
      }
   	
       public String getNome() {
         return nome.getText();
      }
   	
       public void setTelefone(Long telefone) {
         this.telefone.setText(telefone.toString());
      }
   	
       public Long getTelefone() {
         return new Long(telefone.getText());
      }
   	
       public void setEMail(String eMail) {
         this.eMail.setText(eMail);
      }
   	
       public String getEMail() {
         return eMail.getText();
      }
   	
   }

Controle:

   import java.awt.event.ActionListener;
   import java.awt.event.ActionEvent;

    public class AgendaControle {
    
      private AgendaBean b;
      private AgendaModelo m;
      private AgendaView v;
      
       public AgendaControle() {
         
         this.m = new AgendaModelo();
         this.b = new AgendaBean();
         this.v = new AgendaView();
      	
         m.addModeloListener(
                new ModeloListener() {
                   public void atualizar(ModeloEvent me) {
                     v.setPessoa((AgendaBean) me.getSource()); // Pergunta 1
                  }
               }); 
      	
         v.addBotaoCadastrar(
                new ActionListener() {
                   public void actionPerformed(ActionEvent ae) {
                     m.cadastrar(v.getPessoa()); // Pergunta 2
                  }
               });
      }
      
   }

Modelo:

   import java.util.*;
   
    public class AgendaModelo {
    
      private AgendaBean b; // Pergunta 3
    
      private Collection <ModeloListener> modeloListeners = new ArrayList<ModeloListener>();
   
       public void cadastrar(AgendaBean b) {
         this.b = b;
      	// Acessa a camada inferior para persistir...
         this.notificar();
      }
   	
       public synchronized void addModeloListener(ModeloListener ml) {
         if(!modeloListeners.contains(ml)) {
            modeloListeners.add(ml);
         }
      }
   	
       public synchronized void removeModeloListener(ModeloListener ml) {
         modeloListeners.remove(ml);
      }
   	
       private void notificar() {
         Collection <ModeloListener> ml;
         ModeloEvent evento = new ModeloEvent(b);
           
         synchronized (this) {
            ml = (Collection)(((ArrayList) modeloListeners).clone());
         }
      
         for (ModeloListener m : ml) {
            m.atualizar(evento);
         }
      }
   }
    public class AgendaBean {
    
      private String nome, eMail;
      private Long telefone;
   
       public AgendaBean() {
         this.nome="N/C";
         this.eMail="N/C";
         this.telefone = new Long(0);
      }
   	
       public void setNome(String nome) {
         this.nome = nome;
      }
   		
       public String getNome() {
         return this.nome;
      }
   	
       public void setEMail(String eMail) {
         this.eMail = eMail;
      }
   	
       public String getEMail() {
         return this.eMail;
      }
   	
       public void setTelefone(Long telefone) {
         this.telefone = telefone;
      }
   	
       public Long getTelefone() {
         return this.telefone;
      }
   }
    public interface ModeloListener extends java.util.EventListener {
       void atualizar(ModeloEvent e);
   }
    public class ModeloEvent extends java.util.EventObject {
       public ModeloEvent(Object source) {
         super(source);
      }
   }

As perguntas estão no código do controle e no modelo. A 1 e 2 estão comentadas no código do controle, a 3 no modelo.

A pergunta 1 gostaria de saber se está correta a forma de o Observer trazer os dados do modelo para o controle que passa para a visão. Fiquei desconfiada porque no exemplo que segui o controle não faz isso… mas não consegui visualizar outra forma.

A pergunta 2 gostaria de saber se está certa a forma dos dados da visão ser levada ao controle que passa ao modelo? No exemplo que segui o controle parece coletar os dados não diretamente do método get() mas sim do evento. No caso, o source do evento é o JButton… seria obrigada a implementar um Observer para a minha visão toda?

A pergunta 3 é simples mas não sei: É certo instanciar o bean alí? :roll:

Também olhei a última explicação do Lavieri… no caso o controle não pertence a camada nenhuma? AgendaModel.class seriam as regras de negócio?
Acima temos a classe AgendaView.class que está na camada de apresentação, AgendaControle e AgendaIngrid não pertencem a camada nenhuma e as outras o modelo :?:

Acho estar conseguindo… :smiley: Obrigada…
Ficarei aguardando meninos uma confirmação :lol: ou reprovação :cry:

Olá pessoal, sou novo aqui e estou cheio de dúvidas… Já lí boa parte do Tópico mas as dúvidas persistem, são elas:

Quanto ao Fluxo do MVC e MVP:

MVC:

  1. O Controller recebe ações do usuário, nunca a view?
  2. O Controller apenas delega o eventos recebidos da View atualizando o Modelo?
  3. Quem notifica a view das mudanças realizadas no Model pelo Controller: O controller? Através do Observer? Ou pelos dois, dependendo de algo que eu não sei? rs
  4. O Controller fala com a visão?

MVP:

  1. A View é quem recebe ações do usuário, nunca o Presenter?
  2. A view notifica o Presenter que delega a atualização/consulta ao Model?
  3. Quem notifica a view das mudanças realizadas no Model pelo Presenter: O Presenter? Através do Observer? Ou pelos dois, dependendo de algo que eu não sei? rs
  4. O presenter fala com a visão?

Queria saber o processo de cada um deles, assim conseguiria entender mais dos dois e conseguiria tirar uma outra dúvida, qual a diferença entre os 2?

Valeu;

Mesmo não sendo a pessoa certa para responder isso, enquanto isso, vou tentar ajudar. :wink:
Para manter a boa organização, vou citar pergunta por pergunta.

Eu entendo que está correto.

Eu entendo que a forma implementada não é correta. Faria a implementação que citou no final da pergunta (até mesmo olhando um exemplo da página quatorze)

Ao meu ver sim. Senão não tem como você atualizar a visão mandando um evento só com o source da regra. :shock:

[quote=ingridfarabulini]Também olhei a última explicação do Lavieri… no caso o controle não pertence a camada nenhuma? AgendaModel.class seriam as regras de negócio?
Acima temos a classe AgendaView.class que está na camada de apresentação, AgendaControle e AgendaIngrid não pertencem a camada nenhuma e as outras o modelo :?:[/quote]
Essa prefiro deixar para ele responder hehehehe…

Obrigado por continuar usando o tópico, está colaborando muito! :lol:

Não tenho muito tempo agora, então vamos a uma coisa rápida

O problema da sua implementação, Ingrid, é que a classe AgendaControle é na realidade um Presenter e o que vc está tentando fazer é um MVP , não um MVC.
É por isso que está confusa. Vc está fazendo um excelente MVP e achando que é uma porcaria de MVC :slight_smile:

Dito isso, a implementação está em geral correta ( para um mvp)
Apenas alguns detalhes

  1. se usa o agenda bean, não precisa ter get/set para os campos.
  2. telefones são Strings e não integer ( telefones não se somam)
  3. falta um inicio ao seu programa . programas não devem iniciar-se em construtores

Ficaria algo assim

    public class AgendaIngrid {
   		
       public static void main(String args[]) {
         AgendaPresenter presenter = new AgendaPresenter();
          // construtores não começam as coisas... 
            presenter.start();
      }
   }

Visão:

   import javax.swing.*;
   import java.awt.event.*;

    public class AgendaView extends JFrame {
     
      private JTextField nome, eMail, telefone;
      private JButton bCadastrar;
       
       public AgendaView() {
         JPanel p = new JPanel();
         p.add(new JLabel("Nome:"));
         p.add(nome = new JTextField(10));
         p.add(new JLabel(" - Telefone:"));
         p.add(telefone = new JTextField(10));
         p.add(new JLabel(" - E-Mail:"));
         p.add(eMail = new JTextField(10));
         p.add(bCadastrar = new JButton("Cadastrar Pessoa >>"));
         add(p);
         setTitle("Agenda Ingrid vs1.0");
         setSize(720,70);
         setResizable(false);
         setDefaultCloseOperation(EXIT_ON_CLOSE);
        
      }
   
       public void setPessoa(AgendaBean ab) {
         this.setNome(ab.getNome());
         this.setTelefone(ab.getTelefone());
         this.setEMail(ab.getEMail());
      }
   	
       public AgendaBean getPessoa() {
         AgendaBean ab = new AgendaBean();
         ab.setNome(this.nome.getText());
         ab.setTelefone(this.getTelefone());
         ab.setEMail(this.getEMail());
         return ab;
      }
   	
       public void addBotaoCadastrar(ActionListener al) {
         bCadastrar.addActionListener(al);
      }
   	   	
   	
   }

Presenter:

   import java.awt.event.ActionListener;
   import java.awt.event.ActionEvent;

    public class AgendaPresenter {
    
   // só tem acesso ao m e ao v, isso é um presenter. (controles não têm acesso ao v)
      private AgendaModelo m;    
      private AgendaView v;
      
       public AgendaControle() {
         
         this.m = new AgendaModelo();
         this.v = new AgendaView();
      	
         m.addModeloListener(
                new ModeloListener() {
                   public void atualizar(ModeloEvent me) {
                        // ok. Veja que este codigo está realmente no presenter 
                       // e ele que está dicidindo o que fazer com o evento

                       v.setPessoa((AgendaBean) me.getSource()));  


                  }
               }); 
      	
         v.addBotaoCadastrar(
                new ActionListener() {
                   public void actionPerformed(ActionEvent ae) {
                          // idem ao de cima
                     m.cadastrar(v.getPessoa()); 
                  }
               });
      }
      
       public void start(){

               // mostra a view 
                  v.setVisible(true);
         }
   }

Modelo:

   import java.util.*;
   
    public class AgendaModelo {
    
  // o cadastro é simulado aqui por um bean
// poderiamos invocar um serviço ou qq outra coisa.
      private AgendaBean b; 
    
      private Collection <ModeloListener> modeloListeners = new ArrayList<ModeloListener>();
   
       public void cadastrar(AgendaBean b) {
         this.b = b;
      	// Acessa a camada inferior para persistir...
 
            // se acessase nao precisariamos de ter o bean como atributo aqui.
           // por exemplo : session.saveOrUpdate(b);

         this.notificar();
      }
   	
       public synchronized void addModeloListener(ModeloListener ml) {
         if(!modeloListeners.contains(ml)) {
            modeloListeners.add(ml);
         }
      }
   	
       public synchronized void removeModeloListener(ModeloListener ml) {
         modeloListeners.remove(ml);
      }
   	
       private void notificar() {
         Collection <ModeloListener> ml;
         ModeloEvent evento = new ModeloEvent(b);
           
         synchronized (this) {
            ml = (Collection)(((ArrayList) modeloListeners).clone());
         }
      
         for (ModeloListener m : ml) {
            m.atualizar(evento);
         }
      }
   }

[quote=rderoci]Olá pessoal, sou novo aqui e estou cheio de dúvidas… Já lí boa parte do Tópico mas as dúvidas persistem, são elas:

Quanto ao Fluxo do MVC e MVP:

MVC:

  1. O Controller recebe ações do usuário, nunca a view?
  2. O Controller apenas delega o eventos recebidos da View atualizando o Modelo?
  3. Quem notifica a view das mudanças realizadas no Model pelo Controller: O controller? Através do Observer? Ou pelos dois, dependendo de algo que eu não sei? rs
  4. O Controller fala com a visão?

MVP:

  1. A View é quem recebe ações do usuário, nunca o Presenter?
  2. A view notifica o Presenter que delega a atualização/consulta ao Model?
  3. Quem notifica a view das mudanças realizadas no Model pelo Presenter: O Presenter? Através do Observer? Ou pelos dois, dependendo de algo que eu não sei? rs
  4. O presenter fala com a visão?

Queria saber o processo de cada um deles, assim conseguiria entender mais dos dois e conseguiria tirar uma outra dúvida, qual a diferença entre os 2?

Valeu;[/quote]

Desculpa persistir, mas quando der, nao se esqueçam de responder minha pergunta… rs
Preciso muito dessas respostas, visto que em cada canto que eu vejo tenho uma resposta diferente e com isso não consigo me aprofundar no assunto…

Obrigado desde já, galera! Fico no aguardo!

Opa boa tarde! Obrigado por iniciar a sua participação aqui no tópico!

Sim. Quando ocorre uma ação do usuário (click de mouse, pressionamento de tecla, ActionListener, FocusListener,…) esse evento é gerado por um controle e lançado para fora de forma que se outro controle externo estiver escutando (tem um Listener para aquele evento), pode recebê-lo e tratá-lo. Para entender melhor, imagine que na sua visão você inseriu um JButton. Na verdade o que está vendo na sua visão é a visão do JButton. Ao pressionar um botão do mouse sobre ele, um evento é gerado. Mas quem gera esse evento? O controlador, ou seja o próprio JButton. Após o pressionamento do botão, além de gerar esse evento (ActionEvent) ele também faz uma alteração no modelo. Repare que a visão do JButton ao pressionar um botão muda duas vezes de figura, o que reflete duas vezes alterações em seu modelo. Tendo isso em mente, o seu controlador vai registrar um ouvinte na visão que ficará aguardando os eventos lançados pelos controladores que nessa visão estiverem presentes. A imagem mostra isso:

Sim. Aqui pede-se para que use o mínimo possível de lógica.

Então, aqui existe um certo “desacordo” entre companheiros, mas se ler as últimas postagens com bastante atenção, o que realmente torna-se relevante para decidir é a questão da alta coesão e baixo acoplamento. É melhor o controle receber essa notificação da visão e mandar fazer algo na visão. Não está errado, como defendeu o Lavieri em suas postagens. Repare em um desenho do MVC que existe uma seta tarcejada que vai do modelo para a visão, significa chamada indireta, o que justifica a implementação do mesmo. Porém se olhar para imagem, ela indica no MVC que o Ouvinte do modelo deve estar na visão, ou seja o controle atualiza o modelo que notifica a visão da sua alteração e então a visão reenderiza usando o modelo. Veja a imagem:

No MVC pelo que vejo ele só muda a visão que está sendo exibida no momento, como pode apreciar na primeira imagem. Ele não injeta dados na visão.

Não. É o Presenter. (Veja exemplo de código mostrado pela usuária farabulini)

O Presenter que delega a atualização/consulta ao Model. Ele recebe os eventos da visão.

O mais correto seria o Presenter, porém existe um padrão chamado MVPC onde é feito das duas maneiras.

Sim.

Na verdade, o MVP e MVPC é uma derivação do MVC. A diferença é que a lógica de apresentação fica isolada da apresentação em si. MVC surgiu nos tempos do Smalltalk onde controlava um único Widget por vez. Já o MVP foi criado para poder controlar vários Widget’s se uma só vez. Esse link vai responder qualquer dúvida que tenha a esse respeito.

OK? Parabéns por não ter aberto um novo tópico, evitando duplicar tópicos e repetições teóricas, mantendo o bom funcionamento do fórum.
Se continuar com dúvidas volte a postá-las! Felicidades, um abraço, espero ter colaborado.

[quote=pedromuyala]Opa boa tarde! Obrigado por iniciar a sua participação aqui no tópico!

Sim. Quando ocorre uma ação do usuário (click de mouse, pressionamento de tecla, ActionListener, FocusListener,…) esse evento é gerado por um controle e lançado para fora de forma que se outro controle externo estiver escutando (tem um Listener para aquele evento), pode recebê-lo e tratá-lo. Para entender melhor, imagine que na sua visão você inseriu um JButton. Na verdade o que está vendo na sua visão é a visão do JButton. Ao pressionar um botão do mouse sobre ele, um evento é gerado. Mas quem gera esse evento? O controlador, ou seja o próprio JButton. Após o pressionamento do botão, além de gerar esse evento (ActionEvent) ele também faz uma alteração no modelo. Repare que a visão do JButton ao pressionar um botão muda duas vezes de figura, o que reflete duas vezes alterações em seu modelo. Tendo isso em mente, o seu controlador vai registrar um ouvinte na visão que ficará aguardando os eventos lançados pelos controladores que nessa visão estiverem presentes. A imagem mostra isso:

Sim. Aqui pede-se para que use o mínimo possível de lógica.

Então, aqui existe um certo “desacordo” entre companheiros, mas se ler as últimas postagens com bastante atenção, o que realmente torna-se relevante para decidir é a questão da alta coesão e baixo acoplamento. É melhor o controle receber essa notificação da visão e mandar fazer algo na visão. Não está errado, como defendeu o Lavieri em suas postagens. Repare em um desenho do MVC que existe uma seta tarcejada que vai do modelo para a visão, significa chamada indireta, o que justifica a implementação do mesmo. Porém se olhar para imagem, ela indica no MVC que o Ouvinte do modelo deve estar na visão, ou seja o controle atualiza o modelo que notifica a visão da sua alteração e então a visão reenderiza usando o modelo. Veja a imagem:

No MVC pelo que vejo ele só muda a visão que está sendo exibida no momento, como pode apreciar na primeira imagem. Ele não injeta dados na visão.

Não. É o Presenter. (Veja exemplo de código mostrado pela usuária farabulini)

O Presenter que delega a atualização/consulta ao Model. Ele recebe os eventos da visão.

O mais correto seria o Presenter, porém existe um padrão chamado MVPC onde é feito das duas maneiras.

Sim.

Na verdade, o MVP e MVPC é uma derivação do MVC. A diferença é que a lógica de apresentação fica isolada da apresentação em si. MVC surgiu nos tempos do Smalltalk onde controlava um único Widget por vez. Já o MVP foi criado para poder controlar vários Widget’s se uma só vez. Esse link vai responder qualquer dúvida que tenha a esse respeito.

OK? Parabéns por não ter aberto um novo tópico, evitando duplicar tópicos e repetições teóricas, mantendo o bom funcionamento do fórum.
Se continuar com dúvidas volte a postá-las! Felicidades, um abraço, espero ter colaborado.[/quote]

Não entendi essa parte em negrito que você diz a diferença entre os dois… de resto, muito obrigado!!!

No MVC nós temos 1 controller para 1 view e no MVP temos 1 Presenter para n views? Seria isso?

Acrescentando, peguei uma apostila que me diz o seguinte:

MVP versus MVC
?Há mais similaridades do que diferenças entre o MVP e o MVC.
?Diferença principal:
?No MVC, o controller é responsável por capturar as ações do usuário (e.g., mouseDown, keyDown).
?No MVP, é o view que captura as ações do usuário; o presenter então trata esses eventos, atualizando o model.

Não. Várias visões podem ser controladas por um controlador/presenter. No MVC (Smalltalk) você tem o Widget e um controlador específico para ele. No MVP você tem vários Widget’s controlados por um presenter.

[quote=rderoci]Acrescentando, peguei uma apostila que me diz o seguinte:
MVP versus MVC
?Há mais similaridades do que diferenças entre o MVP e o MVC.
?Diferença principal:
?No MVC, o controller é responsável por capturar as ações do usuário (e.g., mouseDown, keyDown).
?No MVP, é o view que captura as ações do usuário; o presenter então trata esses eventos, atualizando o model.
[/quote]
Não. Na minha opinião:

  • O componente view do MVP é 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 (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, mas esses manipuladores meramente passam (delegam) o processamento para o presenter.

Mas, não acredite em mim. Você se baseou em uma apostila não? Então, prefiro que não acredite em mim, só estou expondo o que entendo.
Obrigado por estar aqui, um abraço. :slight_smile:

[quote=sergiotaborda]Não tenho muito tempo agora, então vamos a uma coisa rápida

O problema da sua implementação, Ingrid, é que a classe AgendaControle é na realidade um Presenter e o que vc está tentando fazer é um MVP , não um MVC.
É por isso que está confusa. Vc está fazendo um excelente MVP e achando que é uma porcaria de MVC :slight_smile:
Dito isso, a implementação está em geral correta ( para um mvp)
[/quote]

Sérgio… Obrigada por me ajudar moço, estou muito grata por me atender. :smiley:
Pois é imaginava que seria um MVP mesmo, conforme cheguei a discutir em algumas postagens atrás… :smiley:

Não consigo fazer a implementação em MVC. :cry: Mas vou tentar mais uma vez fazer e postar o código… Sempre que faço tem algo errado… :roll:
Esse MVP até saiu porque segui um exemplo do presenter postado aqui. Mas MVC concluí que nem sei mais por onde começar. :cry:

Ahh e todo esse código pertence a camada de apresentação? Está tudo em um só andar?

Você notou o comentário que coloquei no modelo ‘\ Acessa a camada inferior para persistir…’ e acrescentou um exemplo: ‘session.saveOrUpdate(b);’. No caso, o modelo da camda de apresentação está chamando o objeto ‘session’ da camada de persistência. Esse objeto é uma interface? A camada de persistência usa alguma arquitetura? Obrigada :smiley:

Eu já disse isto antes, mas , aplicações desktop se fazem com MVP. Frameworks gráficos como o swing se fazem com MVC.
Não tente fazer com mvc que não vai dar. Vc está no caminho certo, continue nele.

Sim.

Ai eu usei o exemplo de um objeto do hibernate, mas em geral é uma interface de serviço. o modelo é onde vc chama objetos da camada inferior

A camada de persistencia tb tem arquiteturas especificas. Otrora o DAO era famoso, mas hoje é obsuleto. Hoje em dia se usa o padrão DomainStore.
Vale lembrar que entre a camada de apresentação e a de persistencia ainda está a camada de dominio. Esta é a mais importante.
Nessa camada vc tem padrões como Entity, Value Object, Service e Repository.
Os services são portas de entrada chamadas pelo andar de apresentação e os repositorios são “portas de saida” para o andar de integração (persistencia).

Todos os andares têm padrões particulares a eles.

Olá Sérgio… puxa que bom saber que estou no caminho certo. :smiley: :smiley:
A camada de domínio seriam as classes do diagrama de classes? É onde as coisas realmente acontecem.
Acredito que na parte de apresentação já não tenho mais dúvidas…
Agora vou estudar essa parte, muito obrigada por me ajudar… muito… t+