Compartilhar recursos entre classes de domínio

Estava pensando em adotar um seguinte padrão por questões de centralização.


class Funcionario {
 private Funcionario() {

 }

 public static Funcionario criarNovo() {
     return new Funcionario();
  }

 public static Funcionario consultar(int codigo) {
    return  pegarDoBanco(codigo) ;
 }

 public void salvar() {
    salvarNoBanco(this);
 }

 public void excluir() {
    excluirDoBanco(this);
 }

}

Funcionario f = Funcionario.criarNovo();
f.setCodigo(1);
f.setNome("Maria");
f.salvar();

f = Funcionario.consultar(1);
f.excluir();


Fica interessante ter método estáticos para tratar da “colecao” e métodos de instancia para tratar da individualidade.
O problema é como compartilhar recursos sem deixar a arquitura feia.
ex:


// suponha que exista a classe departamento
Departamento d = Departamento.consultar(1);
Funcionario f = Funcionario.consultar(1);
f.setDepartamento(d);

f.salvar();

ou


Conexao c = new Conexao();

// suponha que exista a classe departamento
Departamento d = Departamento.consultar(c,1);
Funcionario f = Funcionario.consultar(c,1);
f.setDepartamento(d);

f.salvar();

O problema é compartilhar recursos (conexao, parametros , etc) entra as duas classes sem passar parâmetros.

Voce pode deixar a sua Hibernate Session (voce esta usando Hibernate, ne?!) em uma variavel ThreadLocal estatica numa outra classe (Database, por exemplo).

Assim, a sua implementacao de ‘salvar()’ so pega a Session e da um save(this), possivelmente com um flush() em seguida.

Para a conexão existe o pattern Factory que poderia ajudar. Para os parâmetros há interfaces.

Sim Cv estou pensando em usar hibernate, mas por baixo do DAO.
Eu gostaria de compartilhar o Session entre as classes sem passa-lo entr parametros.
Me parece que com esse ThreadLocal eu posso fazer isso.
Ter uma instancia que é compartilhada pela Thread toda e finaliza-la no final da Thread.
Cv vc tem exemplo desse ThreadLocal :lol:
A questão que não é só conexao também cada classe de domínio deve ter informações do contexto da aplicação.

Seu Funcionario não tá fazendo cosia demais não? Eu acho que você esquartejou sua abstraçãod e funcionário dando a ele responsabilidades pelo grupo. Tente Repository

Shoes

Eh simples:

class DatabaseManager {
    private static ThreadLocal userData = new ThreadLocal();

    public static void setConnection(Connection conn) {
        userData.set(conn);
    }

    public static Connection getConnection() {
        return (Connection)userData.get();
    }
    
    public static void finish() {
        Connection conn = getConnection();

        if (conn != null) {
            conn.close();
        }

        // MUITO importante agora:
        userData.set(null);
    }
}

Voce pode ter algo assim. Ai voce chama o setConnection() uma unica vez e depois eh soh usar feliz. Tambem nao esqueca de charmar o finish() no final, senao voce vai ter problemas.

Rafael

E usar isso em EJB é seguro ?

O unico detalhe eh que, como o nome ja diz, os dados sao associados pelo id da thread - ou seja, se voce iniciar uma outra thread, o threadlocal dela sera diferente.

Rafael

Mas para um Session Stateless Bean isso pode dar problema ? Ou Não ?
É um Session Facade , ou seja, chama todos os Domain Classes envolvidos na operação , mas não delego a chamada para outra bean.
ex:


class EJB {
 public void cadastrarFuncionario() {
     DataBaseManager.iniciar();

     Departmento d = DepartamentoRepositorio.consultar(1);
     Funcionario f = FuncionarioRepositorio.criarNovo();
     f.setCodigo(1);
     f.setNome("Maria");
     f.Departamento(d);
     f.cadastrar();

     DataBaseManager.finish();
  }
}

A execução do método do EJB por acaso seria uma única Thread ?

Yeah! Neste exemplo que vc citou não há problema em usar ThreadLocal … está tudo na mesma thread.