Dúvida primária sobre objetos e modelagem

Olá Pessoal,

Tenho duas dúvidas primárias que tenho certeza, serão rapidamente resolvidas:

1- Tenho um objeto Funcionário onde tenho muitas propriedades. O que ocorre é que separei essas propriedades em 3 conjuntos, um com dados obrigatórios e importantes como nome, endereco, cargo etc, outro com dados opcionais não muito relevantes, como Hobies, livros lidos, filmes vistos, um campo de observações etc. E por último dados de configuração, como por exemplo se ele deseja receber e-mail de notícias, e-mail de alertas de reunião, idioma preferível etc.

O mecanismo de inclusão possui 2 telas onde a primeira inclui os campos obrigatórios, o que já faz com que já exista um funcionário (grava o funcionário no banco) e outra com os dados opcionais onde só dou um update nas informações opcionais. As informações de configuração são efetuadas em outro processo.

obs: No banco a tabela de funcionarios tb é dividida em 3 (Func, FuncDet e FuncConfig por exemplo - um pra um - pra um).

Como faço pra modelar esse Funcionário? Terei 3 classes? E o processo de Save quando eu tiver alterando um usuário?

2- E outra dúvida decorrente também deste cenário.
Se eu tenho um objeto Funcionario e outro Funções, onde um funcionário possui um conjundo de funções que ele executa na empresa.
Quando faço um getFunc para recuperar um funcionario e tb recupero as funções como eu faria?

Em Funcionario.Get() eu teria uma chamada a Funcoes.Get(objFuncionario) ?

Funcoes.Get(objFuncionario) já atribuiria as informações das funções ao objFuncionario ou apenas retornaria a colecao de funcoes e no meu Usuario.Get() eu teria Funcionario.Funcoes = Funcoes.Get(objFuncionario) ?

Como disse são dúvidas elementares, mais que provavelmente darão sérios problemas caso não fique bem claro pra mim e eu acabe tomando um caminho errado.

Obrigado a todos que puderem colaborar.
Marcelo.

Isso chama-se herança de classes.

Tu vais precisar fazer 3 classes diferentes, a principal será a Funcionario (a qual tera os atributos padrão), desta vão ser herdadas as classes secundárias (com os atributos que serão opcionais).

Se precisar manipular cada grupo independemento do outro sim. Caso contrario só uma classe.
Se precisar manipular em separado isso significa que não é um cadastro de funcionario que vc tem. Vc tem um cadastro de funcionario ( parte obrigatorio) , um cadastro de configurações do funcionario e outro de interesses do funcionario. São na realidade 3 entidades ligadas por uma composição 1:1 e não uma só entidade.

Sim. Pode fazer isso.

Nenhum dos dois.

class Funcionario{

   public Collection<Funcao> getFuncoes(){
        return  Funcoes.getFuncoesPara(this);
   }

}

opcionalmente vc pode criar um cache

class Funcionario{

   private transient Collection<Funcao> funcoes = null;

   public Collection<Funcao> getFuncoes(){
       if (funcoes ==null)  {
           funcoes = Funcoes.getFuncoesPara(this);
        }
        return  funcoes;
   }

}

[quote=natz]Isso chama-se herança de classes.

Tu vais precisar fazer 3 classes diferentes, a principal será a Funcionario (a qual tera os atributos padrão), desta vão ser herdadas as classes secundárias (com os atributos que serão opcionais).
[/quote]

Na verdade, como o Sergio comentou é uma composição, onde um funcionario teria um Detalhe e uma Configuração e não um Detalhe ser um tipo de Funcionário.

[quote=sergiotaborda]Nenhum dos dois.

class Funcionario{

   public Collection<Funcao> getFuncoes(){
        return  Funcoes.getFuncoesPara(this);
   }

}

[/quote]

Eu acho que escrevi um lance errado e acabei prejudicando meu post. Na verdade eu quis dizer o seguinte:

Pelo que você comentou, o método getFuncoes() da classe Funcionario vai me retornar uma coleção de funções e lá na chamada do getFuncionario eu terei que atribuir esse retorno a Funcionario.Funcoes, correto? Assim: Funcionario.Funcoes = Funcionario.GetFuncoes(). É isso?

A dúvida é onde preencher o objeto Funcoes do usuário.

Com relação as 3 classes, eu concordo que teria uma classe independente chamada de configurações, mais a de interesse não, pq mistura outras propriedades como por exemplo qtd de filhos, fugindo assim do conceito de interesse. De repente isso poderia ser um struct? Não sei se existe isso em java. Seria uma strutura de dados. É uma abordagem interessante?

vlw.

public Collection<Funcao> getFuncoes(){ return Funcoes.getFuncoesPara(this); //aqui }

Isso é necessário quando se usa o Hibernate (por exemplo)? Já que ele também carrega as associações.

Tem algum problema se usar assim:

public Collection<Funcao> getFuncoes(){ return this.funcoes; }

não. Seria como eu exemplifiquei. Não ha atribuição a nenhum atributo de funcionário ( a menos que use o cache que tb exemplifiquei, mas isso é um truque)

eu tinha entendido que a classe Funções faria isso no método getFuncoesPara()

Em java, structs são classes iguais às outras.

Então seria algo assim?

class Funcionario{   
  
   //Este método NAO pode ser estático correto? pq preciso de um funcionario.
   public Collection<Funcao> getFuncoes()   
   {   
        return  Funcoes.getFuncoesPara(this);   //Este método pode ser um método estático?
   }   
  
}  


class Funcoes
{
    public static? Collection<Funcao> GetFuncoesPara(Funcionario objFuncionario)
    {
        Collection<Funcoes> FuncoesDoFuncionario = Acesso o banco e busca as funcoes do funcionario.

         // É aqui que eu associo as funcoes ao meu objeto funcionario?
         objFuncionario.Funcoes = FuncoesDoFuncionario;

        return FuncoesDoFuncionario;
    }
}

É isso?

Sim.
O método pode ser estático. Isso fica ao seu critério.

[quote=joellobo] public Collection<Funcao> getFuncoes(){ return Funcoes.getFuncoesPara(this); //aqui }

Isso é necessário quando se usa o Hibernate (por exemplo)? Já que ele também carrega as associações.

Tem algum problema se usar assim:

public Collection<Funcao> getFuncoes(){ return this.funcoes; } [/quote]

Quando usa hibernate vc tem que usar a segunda forma já que ele trata todo o processo de lazy-loading etc…
mas sem Lazy-loading a amarração de todas as classes umas às outras faz o seu sistema ser hiper-lento.

A primeira versão é para quando vc quer ter mais controle das coisas

hmmmm… Pois é, não tinha lido o post direito… verdade! Desculpa aí!

Valeu Sergio,

Entendi, ficou bem claro agora e bem lógico também.

Estou quebrando a cabeça com esses detalhes bobos, mais é porque esse paradigma (estruturada x objetos) é uma barreira difícil de transpor. São muitas abstraçoes e conceitos.

Um outro cenário um pouco direfente do anterior, mais que eu também não consegui evoluir e chegar numa conclusão satisfatória. Seria o seguinte: Um Coordenador tem um Projeto. Um pra Um. Onde um coordenador coordena um projeto.

Qndo eu crio o Coordenador tb tenho que criar o projeto. Como eu faria isso?
Hoje faço assim:

Na tela de cadastro já tenho todos os campos do coordenador e do projeto, então crio um objeto UmCoordenador e um objeto UmProjeto, e digo que UmCoodenador.projeto = UmProjeto e mando
CoordenadorRepositorio.CriarCoordenador(Coordenador UmCoodenador); e aqui eu faço as duas inclusões,
tanto de coordenador quanto de projeto. Mas isso tá horrível e não sei como melhorar pois para criar um projeto eu preciso do coordenador (do id do Coordenador). Futuramente pode haver a possibilidade de eu precisar criar somente um coordenador, sem o projeto e aí eu to ferrado.

Vou tentar.

class CoordenadorRepositorio
{        
   public Coordenador CriarCoordenador(Coordenador UmCoodenador)     
   {     
        //Gravo o coordenado no banco
        int IdCoordenador = Recupero o ID do coordenador criado 
        UmCoordenador.Id = IdCoordenador;
        return  UmCoordenador;
   }          
}     

class ProjetoRepositorio
{        
   //Aqui eu impaco pq não sei como faço para incluir um projeto que depende de um coordenador
   //Não sei se passo o Coordenador junto com o projeto, não sei se passo o projeto e o id do coordenador
   //Aqui minha lógica é um desastre :))). hellllp
   public Projeto CriarProjeto(Projeto UmProjeto)     
   {     
   
   }          
}     

Obrigado pela paciência ae. Vlw.

[quote=mvurban]Valeu Sergio,

Entendi, ficou bem claro agora e bem lógico também.

Estou quebrando a cabeça com esses detalhes bobos, mais é porque esse paradigma (estruturada x objetos) é uma barreira difícil de transpor. São muitas abstraçoes e conceitos.

Um outro cenário um pouco direfente do anterior, mais que eu também não consegui evoluir e chegar numa conclusão satisfatória. Seria o seguinte: Um Coordenador tem um Projeto. Um pra Um. Onde um coordenador coordena um projeto.

Qndo eu crio o Coordenador tb tenho que criar o projeto. Como eu faria isso?

[/quote]

Essa de 1:1 está meio estranha porque a ideia é que um coordenador coordene vários projetos ao longo da sua vida… mas ok

Um projeto é coordenado ou o coordenador coordena um projeto ? Parece idiota mas não é.
De outra forma: um coordenador tem um projeto ou é associado a um projeto ?
E o projeto ? tem um coordenador ou é associada a um coordenador ?

A resposta é : eles são associados.

Assim sendo vc cadastra um projeto sem coordenador, cadastra o coordenador sem projeto, e depois vc cadastra a associação dos dois. Para diminuir a burocraria vc cadasta o coordenador (sem projeto) e depois cadastra o projeto. No cadastor do projeto vc exisge que seja dito qual é o coordenador do projeto. Quando um for escolhido vc verifica as regras de negocio de que aquele coordenador está apenas naqule projeto.

A classe projeto tem um campo coordenador, e a classe coordenador tem um campo projeto mas a obrigatoriedade do preenchimento é diferente. (para projeto é obrigatorio escolher um coordenador).

Como falei, normalemte é uma relação um para muitos o que torna as coisas mais intuitivas, mas é isso ai…

Opa Sérgio,

Então, um coordenador tem um projeto mesmo. E o projeto tem um coordenador.
Posso ter um coordenador sem projeto, mais o projeto sempre tem um coordenador. No banco a tabela projeto tem uma chave estrangeira que é o id do coordenador.

A inclusao de um projeto depende da inclusão de um coordenador, sempre.

E o processo acontece numa tacada só. Num mesmo evento o coordenador é cadastrado e em seguida o projeto deste coordenador é cadastrado.

Não existe um coordenador e então vou colocar um projeto pra ele.
Não existe um projeto e eu tenho que ter um coordenador pra ele.

A princípio nada existe. Este processo é que cria os dois ao mesmo tempo.