MVC - Camadas

Olá Pessoal !

Estou começando a desenvolver com java e OO, então tenho algumas ( talvez muitas ) dúvidas ainda, talvez primárias, ou não.
É o seguinte.
Estou usando MVC. Até aí tudo bem, já entendi bem como funciona e tal.
Só que me surgiu uma dúvida. Eu posso ter uma camada entre o Controller e o Model ?
Aonde eu vou escrever minhas regras de negócio ? No Controller ?
Eu poderia criar uma camada a mais, tipo ClienteManager, responsável pela regra ?

O que vocês fazem geralmente ?

Salve…Seguinte, da uma lida na apostila FJ21 da Caelum, na parte de DAO(Data Access Object)…tu vai sacar a parada.
To começando agora tbm a usar esse esquema, e essa apostila me ajudou bastante.

To fazendo assim:
classetela - view
classebean - model
classedao - controller

t+ e boa sorte.

Legal Fernnando.
Já dei uma lida na apostila, inclusive fiz o treinamento lá rs Mas cara, acho que não entendeu minha dúvida.

Deixe-me ver se entendi o que você disse.
Você disse pra eu colocar minha regra de negócio no DAO ?

Não sei se faz muito sentido cara.
Pensando num design melhor, aonde faz mais sentido eu colocar minha regra de negócio ?

Existe um modelo chamado de MVC-2 que há sim uma camada a mais, exatamente a Manager que vc refere. Então pode usar sim, crie uma camada a mais e coloque tuas regras de negócio lá.

Entaum, eu faço assim.

//classe de conexao
public class Conexao{
    public static Connection getConnection() throws SQLException{
        try {
             Class.forName("com.mysql.jdbc.Driver");                             
             return DriverManager.getConnection("jdbc:mysql://189.112.114.33/ibgdb?user=juliano&password=31314131");                         
        } catch (ClassNotFoundException e) {
            JOptionPane.showMessageDialog(null, e.getMessage());            
            throw new SQLException();            
        }
        
    }     
}


//classe bean
public class Yperfil{
    private Long id;
    private String perfil;
    private String observacao;     
    
    public void setId(Long id){
        this.id = id;
    }    
    
    public void setPerfil(String perfil){
        this.perfil = perfil;
    }
    
    public void setObservacao(String observacao){
        this.observacao = observacao;
    }
    
    public Long getId(){
        return this.id;
    }
    
    public String getPerfil(){
        return this.perfil;
    }
    
    public String getObservacao(){
       return this.observacao;
    }
    
}


//classe DAO
public class PerfilDAO {
    private Connection con;
    
    public PerfilDAO() throws SQLException {
        this.con = Conexao.getConnection(); //aqui sempre tera uma conexao
    }    
    
    public void insere(Yperfil perfil) throws SQLException{
        //grava um novo perfil
        PreparedStatement stm = this.con.prepareStatement("INSERT INTO yperfil (perfil, observacao) VALUES (?,?)");
        stm.setString(1, perfil.getPerfil());
        stm.setString(2, perfil.getObservacao());
        stm.execute();
        stm.close();
    }
    
    public void altera(Yperfil perfil) throws SQLException{        
        //altera um perfil existente
        PreparedStatement stm = this.con.prepareStatement("UPDATE yperfil SET perfil = ?, observacao = ? WHERE id = ?");
        stm.setString(1, perfil.getPerfil());
        stm.setString(2, perfil.getObservacao());
        stm.setLong(3, perfil.getId());
        stm.execute();
        stm.close();
    }
        
    public List<Yperfil> consulta() throws SQLException{
        //consulta o perfil
        PreparedStatement stm = this.con.prepareStatement("SELECT * FROM yperfil ORDER BY id");
        ResultSet rs = stm.executeQuery();
        List<Yperfil> lista = new ArrayList<Yperfil>(); 
        while(rs.next()){
            Yperfil perfil = new Yperfil();
            perfil.setId(rs.getLong("id"));
            perfil.setPerfil(rs.getString("perfil"));
            perfil.setObservacao(rs.getString("observacao"));
            lista.add(perfil);
        }          
        rs.close();
        stm.close();
        return lista;            
    }
}


//aqui trabalho com a Bean e a DAO
public void inserirPerfil() throws SQLException{
        //grava perfil
        if(!perfilPerfil.getText().isEmpty()){  
             Yperfil perfil = new Yperfil();             
             perfil.setPerfil(perfilPerfil.getText());
             perfil.setObservacao(perfilObs.getText()); 
             
             PerfilDAO perfilDao = new PerfilDAO();
             List<Yperfil> lista = perfilDao.consultaPorDescricaoExata(perfilPerfil.getText());
             if(lista.size() <= 0){                 
                 perfilDao.insere(perfil);                                                   
                 this.usuariosPerfilForm.consultaPerfil();  
                 perfilPerfil.requestFocus();
                 perfilPerfil.selectAll();
                 status.setVisible(true);
                 status.setText("Perfil : " + perfilPerfil.getText() + ", inserido com sucesso");
                 limpaCamposPerfil();
             }else{                
                 JOptionPane.showMessageDialog(null, "Este perfil já está cadastrado.", "Informação", 1, new Metodos().alertaImg("alerta"));
                 perfilPerfil.requestFocus();
                 perfilPerfil.selectAll();
             }
        }else{
             JOptionPane.showMessageDialog(null, "Informe a descrição do perfil", "Informação", 1, new Metodos().alertaImg("alerta"));
             perfilPerfil.requestFocus();
             perfilPerfil.selectAll();
        }
    }

eh isso…t+ e boa sorte

wikipedia: Model-view-controller (MVC) é um padrão de arquitetura de software que visa a separar a lógica de negócio da lógica de apresentação, permitindo o desenvolvimento, teste e manutenção isolado de ambos.

o interessante eh usar o controller para a regra de negocios, nao necessariamente dentro do DAO, mas fazendo uma modelagem na qual principalmente a view esteja separada, só chamando os metodos e etc das outras camadas… dá mais trabalho mas vale muito a pena

acredito que o ClienteManager que voce citou faz muito sentido usar sim, por exemplo nele vc pode guardar um array de Clientes (MODEL) e apresentá-los numa view (ex: TelaClientes)… claro que usando java web voce tem frameworks que te ajudam melhor nisso…

Quando eu tenho alguma lógica que vai trabalhar com duas ou mais entidades (models), crio uma classe Service (ou qualquer outro nome), que vai conter essa lógica específica.

Hm, legal !
Gostei dessa ideia da classe Service j0nny. Mas, seria a mesma coisa que uma Manager? Ou eu teria as duas?

Valeu Pessoal !

[quote=bglbruno]Hm, legal !
Gostei dessa ideia da classe Service j0nny. Mas, seria a mesma coisa que uma Manager? Ou eu teria as duas?

Valeu Pessoal ![/quote]

Acho que não precisaria da Manager tbm, ou crie somente a Manager, o nome, nesse caso, não importa muito, desde que esteje claro para sua equipe qual o papel dessa classe.

Entendi j0nny. Beleza.

Tenho uma outra dúvida agora cara.

Eu tenho a view, que vai conversar direto com o controller.
Então o controller conversa com o Manager / Service, executa toda a regra. E Depois ?
Quem deveria conversar com o DAO / Repository ?

[quote=bglbruno]Entendi j0nny. Beleza.

Tenho uma outra dúvida agora cara.

Eu tenho a view, que vai conversar direto com o controller.
Então o controller conversa com o Manager / Service, executa toda a regra. E Depois ?
Quem deveria conversar com o DAO / Repository ?[/quote]

Controller conversa com seu Service (caso tenha, muito cuidado para não criar Services que apenas delegam funções para alguém), que faz alguma lógica nas suas entidades e persiste (caso precise) usando um Repository ou um DAO.

Eu costumo usar da seguinte maneira:
Controller (Activity quando estou programando para Android) -> Service (caso precise, caso contrário pule essa camada) -> Repository
Repository prefiro que seja apenas uma interface com as operações que devem ser realizadas, ee meu DAO implementa essa interface.
Nesse caso minhas lógicas não sabem da existência de um DAO ou algo parecido.

Mas como falei, muito cuidado com classes que apenas delegam funções.

Certo !
Só não ficou claro uma coisa.

Como assim as lógicas não sabem da existência de um DAO ?
Na classe Service você não vai precisar receber um DAO no construtor ?
E nos métodos eu faria assim, certo ?

public void regraAdicionar(Cliente c){
	/* ... regra para adicionar ... */
	this.dao.adiciona(c);
}

[quote=bglbruno][quote=j0nny]
Repository prefiro que seja apenas uma interface com as operações que devem ser realizadas, ee meu DAO implementa essa interface.
Nesse caso minhas lógicas não sabem da existência de um DAO ou algo parecido.
[/quote]

Certo !
Só não ficou claro uma coisa.

Como assim as lógicas não sabem da existência de um DAO ?
Na classe Service você não vai precisar receber um DAO no construtor ?
E nos métodos eu faria assim, certo ?

public void regraAdicionar(Cliente c){ /* ... regra para adicionar ... */ this.dao.adiciona(c); } [/quote]

Nesse caso que passei pra vc, o DAO implementaria o Repository, então o Service receberia o Repository no construtor, e não o DAO.

Saquei!
Uma outra dúvida que tenho quanto ao repository.
Ele conversa com a base de dados também ? ou somente por meio do DAO ?

Acho que o DAO deveria ficar responsável pelo CRUD basico
E o Repository delegar operações CRUD pro DAO, e outras lógicas além do CRUD, o Repositoty ficar responsável.

Ai o Service não saberia da existência mesmo do DAO, por que o usa é o Repository

Seria essa a estrutura ?

[quote=bglbruno]Saquei!
Uma outra dúvida que tenho quanto ao repository.
Ele conversa com a base de dados também ? ou somente por meio do DAO ?

Acho que o DAO deveria ficar responsável pelo CRUD basico
E o Repository delegar operações CRUD pro DAO, e outras lógicas além do CRUD, o Repositoty ficar responsável.

Ai o Service não saberia da existência mesmo do DAO, por que o usa é o Repository

Seria essa a estrutura ?
[/quote]

Exatamente, o Repository faz a frente das operações, mas quem se responsabiliza mesmo com elas é o DAO.
O Repository não fica responsável por nada além de fazer frente as operações de banco, etc, pq ele é uma interface, e não uma classe.

Legal, entendi.
Bom, acho que por hora não tenho mais dúvidas, vou implementar aqui.

Valeu j0nny !
Valeu Pessoal !