Opinião se esta correto (MVC+Swing)

Pessoal,
Queria uma opinião de vocês se esta correto este exemplo que fiz tentando usar MVC.
Por favor apontem as falhas sem dó kkkk

package modelo;
public class PessoaModelo {
private int id;
private String nome;
private int idade;

public PessoaModelo() {
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getNome() {
    return nome;
}

public void setNome(String nome) {
    this.nome = nome;
}

public int getIdade() {
    return idade;
}

public void setIdade(int idade) {
    this.idade = idade;
}   

}

package controle;

import modelo.PessoaModelo;
import dao.PessoaDAO;

public class PessoasControle {
PessoaDAO pessoaDAO = new PessoaDAO();

public PessoasControle() {      
}

 public void gravar(PessoaModelo pessoa){        
    pessoaDAO.adicionar(pessoa);
}  
 
public void excluir(PessoaModelo pessoa){        
    pessoaDAO.excluir(pessoa);
}   

public void alterar(PessoaModelo pessoa){        
    pessoaDAO.alterar(pessoa);
}   

public void buscar(PessoaModelo pessoa){  
    pessoaDAO.buscar(pessoa);
}   

}

package dao;

import java.sql.*;
import javax.swing.JOptionPane;
import modelo.PessoaModelo;

public class PessoaDAO {
Connection conexao = null;
PreparedStatement pst = null;
ResultSet rs = null;

public PessoaDAO() {
    conexao = ConectorBD.conector();
}

public void adicionar(PessoaModelo pessoa) {
    PessoaModelo pessoaModelo = new PessoaModelo();
    pessoaModelo = pessoa;
    String sql = "insert into pessoas (nome, idade) values(?,?)";
    try {
        pst = conexao.prepareStatement(sql);
        pst.setString(1, pessoaModelo.getNome());
        pst.setInt(2,    pessoaModelo.getIdade());
     
        if (pst.executeUpdate() > 0){
            JOptionPane.showMessageDialog(null, "Pessoa adicionada!");
        }
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}

public void excluir(PessoaModelo pessoa){
    int confirma = JOptionPane.showConfirmDialog(null, "Confirmar exclusão?", "Atenção", JOptionPane.YES_NO_OPTION);
    if (confirma == JOptionPane.YES_OPTION){
        PessoaModelo pessoaModelo = new PessoaModelo();
        pessoaModelo = pessoa;
        String sql = "delete from pessoas where id = ?";
        try {
            pst = conexao.prepareStatement(sql);
            pst.setInt(1, pessoaModelo.getId());
            if(pst.executeUpdate() > 0){
                JOptionPane.showMessageDialog(null, "Excluido com sucesso");
            }
        }catch (Exception e) {
            JOptionPane.showMessageDialog(null, e);
        } 
    }
}

public void alterar(PessoaModelo pessoa) {
    PessoaModelo pessoaModelo = new PessoaModelo();
    pessoaModelo = pessoa;
    String sql = "update pessoas set nome = ?, idade = ? where id = ?";
    try {
        pst = conexao.prepareStatement(sql);
        pst.setString(1, pessoaModelo.getNome());
        pst.setInt(2,    pessoaModelo.getIdade());
        pst.setInt(3,    pessoaModelo.getId());
     
        if (pst.executeUpdate() > 0){
            JOptionPane.showMessageDialog(null, "Dados alterados!");
        }
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}

public void buscar(PessoaModelo pessoa){
    PessoaModelo pessoaModelo = new PessoaModelo();
    PessoaModelo pessoaModeloResposta = new PessoaModelo();
    String sql = "select * from pessoas where id = ?";
    try {
         pst = conexao.prepareStatement(sql);
         pst.setInt(1, pessoa.getId());  
         rs = pst.executeQuery();  
         
        if(rs.next()){ 
           pessoa.setId(rs.getInt("id")); 
           pessoa.setNome(rs.getString("nome"));               
           pessoa.setIdade(rs.getInt("idade"));                             
        }else{
            JOptionPane.showMessageDialog(null, "Não achou ninguem!");
        }             
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }               
}    

}

package visao;

import modelo.PessoaModelo;
import controle.PessoasControle;

public class PessoaVisao extends javax.swing.JFrame {

PessoaModelo pessoaModelo = new PessoaModelo();
PessoasControle pessoaControle = new PessoasControle();

public PessoaVisao() {
    initComponents();       
}

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jLabel1 = new javax.swing.JLabel();
    jLabel2 = new javax.swing.JLabel();
    jLabel3 = new javax.swing.JLabel();
    jTextField1 = new javax.swing.JTextField();
    jTextField2 = new javax.swing.JTextField();
    jTextField3 = new javax.swing.JTextField();
    jButton1 = new javax.swing.JButton();
    jButton2 = new javax.swing.JButton();
    jButton3 = new javax.swing.JButton();
    jButton4 = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jLabel1.setText("ID");

    jLabel2.setText("Nome");

    jLabel3.setText("Idade");

    jButton1.setText("Gravar");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });

    jButton2.setText("Excluir");
    jButton2.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton2ActionPerformed(evt);
        }
    });

    jButton3.setText("Alterar");
    jButton3.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton3ActionPerformed(evt);
        }
    });

    jButton4.setText("Buscar");
    jButton4.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton4ActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextField3)))
                .addGroup(layout.createSequentialGroup()
                    .addComponent(jButton1)
                    .addGap(18, 18, 18)
                    .addComponent(jButton2)
                    .addGap(18, 18, 18)
                    .addComponent(jButton3))
                .addGroup(layout.createSequentialGroup()
                    .addComponent(jLabel1)
                    .addGap(18, 18, 18)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(18, 18, 18)
                    .addComponent(jButton4)))
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel1)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jButton4))
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel2)
                .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel3)
                .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jButton1)
                .addComponent(jButton2)
                .addComponent(jButton3))
            .addContainerGap(24, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>                        

//BOTAO GRAVAR
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    pessoaModelo.setNome(jTextField2.getText());
    pessoaModelo.setIdade(Integer.valueOf(jTextField3.getText()));
    
    pessoaControle.gravar(pessoaModelo);
}                                        

//BOTAO EXCLUIR
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    pessoaModelo.setId(Integer.valueOf(jTextField1.getText()));
    pessoaControle.excluir(pessoaModelo);
}                                        

//BOTAO ALTERAR
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
   pessoaModelo.setId(Integer.valueOf(jTextField1.getText()));
   pessoaModelo.setNome(jTextField2.getText());
   pessoaModelo.setIdade(Integer.valueOf(jTextField3.getText()));
    
   pessoaControle.alterar(pessoaModelo); 
}                                        

//BOTAO BUSCAR
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                                         
   pessoaModelo.setId(Integer.valueOf(jTextField1.getText()));
   pessoaControle.buscar(pessoaModelo);
                          
   jTextField1.setText(Integer.toString(pessoaModelo.getId()));
   jTextField2.setText(pessoaModelo.getNome());
   jTextField3.setText(Integer.toString(pessoaModelo.getIdade()));       
}                                        

public static void main(String args[]) {
     java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new PessoaVisao().setVisible(true);
        }
    });
}
// Variables declaration - do not modify                     
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JButton jButton4;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
// End of variables declaration                   

}

Se esta funcionando, eu acredito que não tem erro nehum, está bom!

e onde vc está fechando a conexão q vc cria qnd instancia a DAO?

Realmente não estou fechando, até me lembro de ter comentado o código depois retirado.
Mas estou querendo uma opinião sobre o MVC, acha que esta correto? se tem algo fora do lugar?

Não está ruim não.
O correto é relativo, acima de tudo deve funcionar perfeitamente, por exemplo, de momento se preocupe com as conexões q n estão sendo fechadas ao invés do padrão. Eu n criaria aquela controller só pra encaminhar a chamada pra DAO, chamaria a DAO direto da tela. E dentro da DAO n tem pq ter o PreparedStatement e ResultSet global.
Quanto as conexões ainda, vc pode fazer do modo simples ou do hardcore.
Simples: cria e fecha uma conexão toda vez q precisar. Ou seja, cada método da DAO abriria a conexao, faria oq precisa ai fecharia. Recomendo este se está iniciando.
Hardcore: criar um verdadeiro pool de conexões para q possam ser reutilizadas.

Obrigado pelo retorno

Obrigado pelo retorno Rodrigo, valeu mesmo

A meu ver, o maior erro é os professores ensinarem a separar o model, view e controller em pacotes.
A literatura não ensina isso, o controller deveria estar no mesmo pacote que as classes da view que ele vai manipular, senão o desenvolvedor é obrigado a tornar público métodos da view que não deveriam ser públicos.

MVC se refere à separação de responsabilidades, não de pacotes.

Faz sentido sua posição! mas acho que para quem esta começando, uma separação dessa ajuda a não confundir tanta a cuca.

valeu

Dentro dos métodos da sua classe DAO você faz o seguinte trecho de código:

Acho desnecessário criar uma nova instância de um objeto somente para atribuir o objeto enviado por parâmetro, eu utilizaria o que vem por parâmetro!

Removeria também da classe DAO os JOptionPane, trataria as mensagens diretamente na view, ou em um outro objeto designado para tratativa de mensagens, por se tratar se um objeto visual.

Sua classe Controller está apenas fazendo uma ponte entre a View e a Dao, nesse contexto em que foi usada acho desnecessário!
Poderia chamar os métodos diretamente da DAO, isso vai reduzir a quantidade de classes e instâncias de objetos.

Obrigado pelas dicas Jonathan.