Modelagem PessoaFisica,PessoaJuridica,Cliente usando Hibernate

39 respostas
E

Olá pessoal,

Está é mais uma dúvida sobre uma assunto que já é antiga aqui no fórum visto pelo número de postagens sobre o assunto. No entanto mesmo lendo estes posts eu ainda fiquei com dúvida. Então gostaria de uma ajuda de vocês que entedem bem sobre o assunto.

A minha dúvida inicial era sobre como modelar uma Classe de Cliente, sendo que o cliente pode ser uma Pessoa Física ou Jurídica. Agora eu tenho modelado da forma que acredito ser suficiente.

Modelagem das classes:

  1. Criei uma Classe Abstract para Pessoa: public abstract class Pessoa
  2. Criei uma SubClasse para PessoaFisica: public class PessoaFisica extends Pessoa
  3. Criei uma SubClasse para PessoaJuridica: public class PessoaJuridica extends Pessoa
  4. Criei uma Classe para Cliente (composição)
public class Cliente {

private Pessoa pessoa;

…

public setPessoa(Pessoa pessoa)…

public Pessoa getPessoa();

…

}

Ai idéia era simples, sendo a classe Pessoa Abastract eu era forçado a instanciar usando a Classe PessoaFisica ou Juridica conforme o tipo do cliente e quando eu precise pegar os dados inerente a uma PessoaFisica ou PessoaJuridica eu simplesmente faria um Cast conforme o tipo do cliente.

Mas aqui está a duvida como fazer o Mapping do hibernate nesta situação via XML?

No banco de dados existem 4 tabelas diferentes:
Uma Para Pessoa (PK CodigoPessoa)
Uma Para PessoaJuridica (PK CodigoPessoa FK com CodigoPessoa)
Uma Para PessoaFisica (PK CodigoPessoa FK com CodigoPessoa)
Uma Para Cliente (PK CodigoPessoa FK com CodigoPessoa)

O Configuração da Pessoa.hbm.xml tá feita e funcionando, o problema esta em como mapear o attributo pessoa da classe Cliente para que o mesmo funcione quando eu for dar um load, ou seja, instancie a Classe correta conforme o tipo do cliente (PF ou PJ).

Pessoal, vocês acham que está forma acima é viagem, tá tudo furado o conceito?

Obrigado pela atenção

39 Respostas

S

cara você conhece bem o conceito de herança ?

como assim, subclasse sem herança ??

E

Conheco sim!, :D, dei um Ctrl+C e Ctrl+V e acabei esquecendo de mudar, foi mau.

A frase “Criei um SubClasse Cliente (não é herança)” está errada.

Já editei o post e corrigi, somente para reiterar, a classe Cliente é uma composição de uma Pessoa.

Obrigado pelo aviso,

T
Olá Só uma dúvida: há realmente a necessidade de usar composição na relação Cliente - Pessoa? Acho que só seria preciso fazer dessa forma se você fosse mudar a pessoa associada ao Cliente em tempo de execução... Seguindo a lógica, um cliente É - e não TEM - uma pessoa. Acho que você tá levando a regra da composição ao pé da letra demais. Segue uma sugestão de implementação, que permite você determinar dinamicamente se uma pessoa será física ou jurídica:
public interface CadastroNacional {
	// Nas subclasses, você pode lançar um IllegalArgumentException se o cpf ou cnpj não for válido
	public void validar();
}

public class CPF implements CadastroNacional {
	private String cpf;

	public CPF(String cpf) {
		this.cpf = cpf;

		validar();
	}

	public void validar() {
		// Código de validação de CPF
	}

	public String toString() {
		// Sobrescrevendo o método toString para formatar o cpf de forma adequada
	}
}

public class CNPJ implements CadastroNacional {
	private String cnpj;

	public CNPJ(String cnpj) {
		this.cnpj = cnpj;

		validar();
	}

	public void validar() {
		// Código de validação de CNPJ
	}

	public String toString() {
		// Sobrescrevendo o método toString para formatar o cnpj de forma adequada
	}
}

// Note que esta classe não é abstrata
public class Pessoa {
	// Olha a composição aqui
	private CadastroNacional cadastro;

	public void setCadastroNacional(CadastroNacional cn) {
		// Aqui você pode passar um objeto do tipo CPF ou CNPJ
	}
}

// Você ainda precisa da classe Cliente? Se sim, aqui vai:
public class Cliente extends Pessoa {

}
Se você preferir, pode fazer CadastroNacional uma classe abstrata em vez de uma interface. Abraços
P

Você realmente precisa dessa hierarquia toda? O exemplo de Pessoa como suerclasse de Pessoa Jurdica e Fisica é muito utilizado mas é um dos exemlos mais infelizes que existem. Acho que a solução do tnaires é razoável mas eu rocaria toda a complexidade por apenas uma classe e um Strategy no validador, creio.

_

Mas como, por exemplo, eu conseguirei atribuir um endereço a uma pessoa.

Uma pessoa, pode ter vários endereços.

E um endereço pode ser de uma pessoa fisica, ou juridica …

Nesse caso, justifica-se a herança de Pessoa -> Pessoa Fisica | Pessoa Juridica

P

_filipe:
Mas como, por exemplo, eu conseguirei atribuir um endereço a uma pessoa.

Uma pessoa, pode ter vários endereços.

E um endereço pode ser de uma pessoa fisica, ou juridica …

Nesse caso, justifica-se a herança de Pessoa -> Pessoa Fisica | Pessoa Juridica

Se uma pessoa juridica pode ter varios enderecos e uma pessoa fisica soh pode ter um quantos enderecos tem a pessoa? Pessoa nao tem endereco?

Se voce fizer desta forma o codio que lida com enderecos nao eh polimorfico. Se este codio nao for polimorfico ele tem que tratar cada caso como m caso. Se ele nao eh polimorfico voce ja nao esta fazendo uso de heranca.

Ja que voce nao esta fazendo uso de heranca que tal assumir que uma pessoa tem 0 (ou 1, depende do dominio) ou mais enderecos? Vai atender os dois casos e voce nao ganhou nem perdeu nada alem de evitar uma hierarquia que conceitualmente nao existe e em termos de implementacao nao te da nada.

Note que eu nao estou dizendo que essa hierarquia nunca deva ser utilizada, ela pode fazer sentido em alguns casos mas eu nunca vi. E olha que ja trabalhei com billing de telefonia, previdencia privada e planos de saude, dominios que sao cheios de situacoes onde peoas fisicas e juridicas se confundem.

_

Tah, vamos la

Eu tenho uma entidade endereço, e uma entidade pessoa e outra pessoa jurídica.

Pessoa e Pessoa Jurídica são entidades diferentes (Não tem relação entre si).

Uma Pessoa tem um ou muitos endereços.

Uma Pessoa Jurídica tem apenas um endereço. (Não tem sentido uma Pessoa Jurídica tem vários endereços, uma Pessoa Jurídica tem filiais certo ?)

Como seria a representação em classes ?

Na boa, a cada dia que passa, percebo que OO ainda possui algumas limitações e paradigmas

----------------------------

tnaires:
Olá Só uma dúvida: há realmente a necessidade de usar composição na relação Cliente - Pessoa? Acho que só seria preciso fazer dessa forma se você fosse mudar a pessoa associada ao Cliente em tempo de execução... Seguindo a lógica, um cliente É - e não TEM - uma pessoa. Acho que você tá levando a regra da composição ao pé da letra demais. Segue uma sugestão de implementação, que permite você determinar dinamicamente se uma pessoa será física ou jurídica:
public interface CadastroNacional {
	// Nas subclasses, você pode lançar um IllegalArgumentException se o cpf ou cnpj não for válido
	public void validar();
}

public class CPF implements CadastroNacional {
	private String cpf;

	public CPF(String cpf) {
		this.cpf = cpf;

		validar();
	}

	public void validar() {
		// Código de validação de CPF
	}

	public String toString() {
		// Sobrescrevendo o método toString para formatar o cpf de forma adequada
	}
}

public class CNPJ implements CadastroNacional {
	private String cnpj;

	public CNPJ(String cnpj) {
		this.cnpj = cnpj;

		validar();
	}

	public void validar() {
		// Código de validação de CNPJ
	}

	public String toString() {
		// Sobrescrevendo o método toString para formatar o cnpj de forma adequada
	}
}

// Note que esta classe não é abstrata
public class Pessoa {
	// Olha a composição aqui
	private CadastroNacional cadastro;

	public void setCadastroNacional(CadastroNacional cn) {
		// Aqui você pode passar um objeto do tipo CPF ou CNPJ
	}
}

// Você ainda precisa da classe Cliente? Se sim, aqui vai:
public class Cliente extends Pessoa {

}
Se você preferir, pode fazer CadastroNacional uma classe abstrata em vez de uma interface. Abraços

Como seria a implementação disso no mapeamento com o hibernate ?

P

Como você quiser. Se elas não sao da mesma hierarquia não entendi o problema.

_filipe:

Na boa, a cada dia que passa, percebo que OO ainda possui algumas limitações e paradigmas

Orientação a Objetos é um paradigma então não sei e entendi o que você quiz dizermas sim, como qualquer outro e limitado. Só não deixe que a linguagem te limite mais ainda, tente modelar isso em Ruby e algumas das limitações ipostas por tipagem estática em Java somem.

_

Ola

O grande problema é o seguinte, vou tentar ser mais prático.

A meses venho tentando descobrir uma solução para esse problema:

Duas entidades não relacionadas, distintas, possuem associação a uma entidade qualquer.

Exemplo:

Temos 3 classes:

Entidade Pessoa Física

  • id
  • nome
  • Collection de Telefones

Entidade Pessoa Jurídica

  • id
  • razão social
  • Collection de Telefones

Entidade Telefone

  • id
  • numero
  • A referencia para proprietário pode ser tanto para uma pessoa juridica, quanto fisica.

Entende mais ou menos aonde eu quero chegar ?

Pessoa Física, e Pessoa Juridica são entidades distintas, e ambas possuem uma lista de telefones, quando, eu vou modelar minha classe Telefone, preciso especificar quem é o proprietário da linha, porém o proprietário pode ser tanto uma pessoa física, quanto juridica !

P

O que você quer fazer é alo muito comum. Se você precisa modelar as ‘pessoas’ como classes separadas elas precisam ter um ancestral em comum (em Java) e você az com que o Proprietario do telefone seja deste tipo. É o que foi sugrido no início deste tópico:

class PessoaJuridica extends/implements Pessoa {}
class PessoaFisica extends/implements Pessoa {}
class Telefone{

 private Pessoa proprietario=null;
}

Isso é uso de polimorfismo.

O meu ponto é que esta modelagem de PesoaFisica e PessoaJuridica como duas classes diferentes não é mito eliz porque dificilmente você precisa deste nível de detalhe. Na maioria dos casos ser pf ou pj é um atributo da pessoa e não justifica a criação de ma classe própria.

_

Entao, mas tu não concorda comigo, que pessoa juridica tem atributos/caracteristicas diferentes de uma pessoa fisica … uma pessoa fisica possui rg, cpf, data de nascimento, uma pessoa juridica possui cnpj, funcionários e etc …

não é mais viável, tratar como coisas distintas ?

P

Depende do que você precisa, do que é o domínio do seu sstema. Talvez elas possam ser classes diferentes sm e talvez não precisem de um ancestral em comum. Ou talvez realmente um ancestral em comum eja necessário. Ou talvez apenas os dados devam ficar em uma clase isolada que varia de um para otro. Depende.

O que não dá é para assumir que a relação PF extends P, pj extends P seja uma regra como vemos na maioria das vezes. Tudo depende do que você está fazendo.

_

Saquei :wink:

ps: valeu pela ajuda meu querido !

_

Utilizando o mesmo exemplo que citei do telefone.

não é coerente criar uma interface pessoa, e sim uma classe pessoa.

é viável manter nessa classe pessoa (ancestral) uma collection de telefones ?

Ou a pessoa não deve possuir essa associação direta …

Outra dúvida:

Quais seriam os atributos da classe pessoa, apenas id, nome (olhe lá) e data de registro por exemplo ?

Os dados mais especificos estariam em suas classes filhas …

Abstraindo para o mundo real, acho que essa não seria a solução mais elegante para essa modelagem, mas nem pra tudo existem soluções elegantes !

P

Porque não seria coerente uma interface? Vai depender do que você espera de um Proprietario. Usar interfaces geralmente é melhor, tanto do ponto de vista técnico (proxies dinâmicos, hrança múltipla) quanto de modelagem (você especiica um comportamento e não uma implementação). Usar uma superclasse para esta relação geralmente só é vantagem quando ela não é abstrata e/ou já possui um bom candidato dentro suas classes, não precisa criar ma classe só para isso.

Mas tendo ou não uma interface a ergunta e: qual a vantagem em ter uma lista na superclasse? A uperclasse deve contêr coisas que são caracteristicas de todos os seus filhos, ter uma lista é uma delas? Voltando ao exemlo da interface, será que o que você precisa não é apenas que a classe tenha um método que retorna o(s) telefone(s)? Será que é tão importante como isso é implementado?

Os dados específicos ficam nas filhas, apesar que eu não conheço seu modelo o suficiente para achar que vcê deva ter essa herança de qualquer modo.

_

Legal cara, bacana

Entendi aonde quer chegar, ja imaginava que seria dificil ter uma resposta sem lhe enviar a modelagem do sistema e as especificações …

Mas me ajudou muito …

Agora, suponhamos que eu utilize interface para a pessoa, é possível mapear isso no hibernate ?

Quero dizer, eu precisarei criar uma tabela Pessoa !?

P

Você não persiste a interface, persiste a implementação. Pro ORM não importa.

_

uhnm cara,

então complicou, pq de acordo com a minha duvida no contexto Pessoa Juridica, Pessoa Fisica e Telefones, eu tinha pensado em um modelo fisico de banco de dados mais ou menos assim:

Pessoa

  • id (pk)
  • nome

PessoaFisica

  • Pessoaid (fk)
  • dataNascimento

PessoaJuridica

  • PessoaId (fk)
  • cnpj

Telefones

  • id
  • pessoaId (fk)
  • numero

vou ter que pensar em outra modelagem agora … algo mais proximo de:

PessoaFisicaTelefones

  • pessoaFisicaId
  • TelefoneID
  • Tipo

certo ?

_

Se fizer algo parecido com o citado acima, eu vou ter tantas tabelas no meu banco de dados … que vai ser complicadisso manter …

T

Filipe, você se preocupa muito com banco de dados! :smiley:
Estude um framework de persistência ORM e você verá que nunca mais precisará desenvolver um banco de dados.
Abraços

_

Então

Em minhas aplicações eu uso o hiberbante mais alguns outros patterns como DAO e etc …

Pelo oque ouvi dizer, frameworks de persistencia ORM não são aconselhaveis para uso em aplicações complexas.

Tipo, voce teria alguma dica de um framework de persistencia ORM ? O hibernate não seria um !? Se sim, como não me preocupar com o banco de dados?

S

_filipe:
Se fizer algo parecido com o citado acima, eu vou ter tantas tabelas no meu banco de dados … que vai ser complica disso manter …

por isso que você não vai manter. Você vai deixar algum framework manter.
Afinal vc está fazendo java ou programação-de-banco-de-dados-disfarçado-de-java ? :wink:

_

Entao, quando quiz dizer manter, não foi pensando na aplicação, e sim no banco de dados.

Realmente, estou preocupado com o banco de dados, pois estou pensando em objetos e no mapeamento do mesmo com as tabelas do meu banco. (É errado pensar assim?)

abras

T

O que seriam aplicações complexas? Particularmente, eu nunca ouvi falar dessas limitações do Hibernate. Mas não posso falar que já vi aplicações críticas utilizando-o.

Sim, o Hibernate é um exemplo.

Não é que você não tenha que se preocupar com o banco, e sim, você não precisa se preocupar em desenvolvê-lo. Você constrói o seu modelo utilizando suas classes e se preocupa apenas com ele. Modificações que por ventura venham a ser necessárias no seu modelo refletirão diretamente no banco de dados.

_

Uhnm … entendi

beleza

valeu galera :smiley:

T

Veja este livro excelente sobre Hibernate (um dos autores é o criador do framework, Gavin King).
Abraços

Q

Sempre fiz da seguinte maneira.

Faz uma classe Pessoa com (Id, Nome, DtRegistro, Endereco endereco, Telefone[] tel) dai por herança(extends) vc faz sua PessoaFisica e PessoaJuridica.

dai no hibernate vc mapeia a PessoaFisica e PessoaJuridica, como elas estão herdando as propriedades de Pessoa o hibernate já reconhece os atributos.

A

Na minha opinião, uma interface ou implementação chamada simplesmente “Pessoa” só deveria existir em um sistema, se existir uma entidade chamada ExtraTerrestre ou Animal que possa entrar em conflito de comportamento com a tal “Pessoa”.

Pessoa é algo muito genérico, posso estar enganado mas fatalmente essa modelagem possa ser modelada ao ponto de ficar mais clara.

J

Com todo respeito e sem querer causar polemicas, vejo muita gente se preocupando em generalizar o maximo seu DAO, estudando afoitamente hibernate e o pior de tudo se gabando por estão programando em poo. Novamente não quero causar polemica pelo contrario, onde eu quero chegar é que existe uma lacuna enorme entre uma modelagem bem feita e o uso de framework e conceitos ddd. Vejo professores de faculdade usando o exemplo de pessoafisica herda pessoa e pseesoajuridica herda pessoa e na próxima aula mostrando hibernate e o conceito de DAO(que é outro ?erro? pois não vejo vantagem em ter um DAO com hibernate já que o mesmo pode fazer o papel do de DAO, a menos que não tenhamos um SGDB e sim um outro mecanismo de armazenagem de dados, bom mas isso é um outro assunto), se um professor usa esse exemplo de modelagem ?ridícula?, não precisa nem ensinar DAO.

Voltando ao problema, acho muito importante debatermos o assunto desse tópico pois não vale nada usarmos poo sem ter uma modelagem apropriada. Minha humilde opnião:
1 não existe pessoafisica e nem pessoajuridica
2 existe sim Pessoa, pense em pessoa como um ser humano
3 existe sim empresa, pense em empresa como um prédio(parece obvio)
4 Esqueça cpf e cnpj como conceito que separam uma pessoa de uma empresa, o que separa uma pessoa de uma empresa é o fato de pessoa ser uma pessoa, ou melhor ter ou não comportamento diferente de uma empresa. A outro detalhe cpf e cnpj são identificações somente aqui no Brasil, mais uma razão para esquecer pf e pj.

A melhor maneira, acho, é começar a modelar pela utilização de pessoa ou empresa dentro do sistema. Bom seu sistema é de venda, então seu sistema terá um cliente, cliente terá um comportamento certo, daí pergunto, qual a diferença quando na loja que usa o sistema o cliente que compra ser uma pessoa ou uma empresa?
Se nenhuma, então simplesmente crie uma interface cliente, daí crie uma person que implementa cliente. Para saber se a person é uma pessoa ou uma empresa crie um método person.isEmpresa. daí aqui não teremos a classe pessoa e nem empresa, mto menos PJ e PF.
Agora se sim, existe diferença entre uma pessoa compra ou uma empresa(lembrando que quem compra é um cliente), por exemplo, o calculo de desconto de uma empresa é diferente de uma pessoa a sim crie duas classes. Empresa implementa cliente e Pessoa implementa cliente. Para venda não importa se cliente é ou não empresa, mas para o sistema sim. Daí quando a venda for calcular por exemplo Cliente.meudesconto(produto) vai usar aqui poliformismo e sim fara sentido ter 2 classes, empresa e pessoa. Lembrando novamente que não existe cadastro de pessoa e empresa e sim de clientes, para o sistema dificilmente vai existir o papel de pessoa e empresa e sim cliente.

Acho que minha explicação ficou meio complica, desculpas, bom se esse assunto fomentar, ?posto ? novamente.

L

Cara vc poderia fazer o Pessoa Juridica herdar de Pessoa Fisica ficaria bem mais interesante e economizaria classes… pq veja uma Pessoa tera: nome, telefone, endereco, data de nascimento, cpf, uma pessoa Juridica tera todos os mesmos atributos e mais razão social, numero de funcionrios, inscrição estadual, etc…
ao meu ver tera um atributo distinto que tem em uma pessoa e nao tera em uma pj o cpf… porem este atributo vc pode generalisar em pessoa dando o nome de codigoPessoa por exemplo em pessoa fisica seria o cpf e em pessoa juridica o cnpj… creio que fazendo uma modelagem assim isto simplificaria seu codigo…

T

Cara, concordo com tudo o que você disse.

O Transaction Script (managers com regras de negócio que instanciam VOs disfarçados de entidades do Hibernate e chamam os DAOs para persistí-los) é muito difundido, e é impressionante a quantidade de pessoas que acham que essa é a única forma de modelar a camada de negócios em Java. Pois é a única forma que elas vêem em cursos, pós-graduações e em empresas ( claro que existem exceções, mas aqui onde moro eu nunca vi ). Pior, essas pessoas dizem que estão programando OO. Elas mal sabem que separar dados de comportamento não é exatamente OO - e continuam sem saber - porque não estão dispostas a sentar o rabo na cadeira e estudar fora do ambiente de trabalho ou da faculdade.

[DESABAFO MODE=ON]

Vejo muito esse tipo de atitude passiva nos profissionais. Às vezes tento mostrar as outras opções, apontando artigos e livros, mas acabo sendo ignorado. As pessoas dizem: “beleza, depois vou dar uma olhada”, como se tivessem fazendo um favor a mim, e não a elas. :? Pior é quando a gente sugere usar alguma tecnologia nova: inventam mil desculpas, dizem que não têm tempo, que precisam requerer treinamento, etc etc. Depois essas mesmas pessoas começam a vomitar palavras bonitas, dizendo “ah, precisamos aplicar padrões de projeto, etc etc”, e ainda ficam criticando os programadores COBOL que não querem se atualizar :x

Uma das melhores coisas que aprendi aqui no GUJ foi a sempre procurar me manter atualizado. Conviver com “monstros” como o shoes, cv, Maurício Linhares, Luca, e vários outros que não citei, é realmente muito estimulante.

[DESABAFO MODE=OFF]

Não estou criticando o TS. Há situações em que ele é realmente útil e produtivo. Mas quem usa e diz que programa OO precisa mesmo estudar mais um pouco.

S

Joaquimnabuco:
Vejo professores de faculdade usando o exemplo de pessoafisica herda pessoa e pseesoajuridica herda pessoa e na próxima aula mostrando hibernate e o conceito de DAO(que é outro ?erro? pois não vejo vantagem em ter um DAO com hibernate já que o mesmo pode fazer o papel do de DAO, a menos que não tenhamos um SGDB e sim um outro mecanismo de armazenagem de dados, bom mas isso é um outro assunto), se um professor usa esse exemplo de modelagem ?ridícula?, não precisa nem ensinar DAO.

finalmente alguem que entendeu o problema. É isso mesmo. DAO com hibernate é rídiculo. Pessoa fisica e Juridica como herança de Pessoa é ridiculo. Acrescento também a modelagem de Cliente como herança de Pessoa.

Calma, calma. Existir existe. São duas figuras juridicas ( do Direito). As leis que se aplicam a uma não se aplicam necessáriamente à outra. ( os principios se aplicam às duas e por isso as duas se chamam pessoa. Mas este conceito de “pessoa” nada tem a haver com “ser humano” ou “individuo”)

Parece, mas não é. Empresa não é um prédio. Empresa são várias coisas. É uma organização de individuos. Por isso que existe uma hirarquia. É uma figura juridica ( do Direito) com responsabilidades, direitos e deveres. Entre outras.
É porque “empresa” é um conceito rico que é necessário uma coisas como um ERP.

Mas estaremos mantando o polimorfismo tendo que identificar o tipo de pessoas que temos. É exacatamente isso que é errado. O ponto é “Não diferencie individuo de empresa”.

Vai sim. Esse é o problema.
A venda gera obrigações para quem vende. Uma delas é entregar o produto, outra é pagar impostos. O imposto retido/pago é diretamente influenciado se o comprador é uma empresa ou não. Se é uma empresa , que tipo de empresa ? Existe muitos detalhes que influenciam no calculo dos impostos ( outro é o proprio produto). E esta é a razão principal de diferencia pessoa individuo e pessoa empresa. No clipper fazia-se assim " if (empresa) { } else { } " esse if está ai até hoje.

É importante fazer uma analise ( separação do todo) para entender o pq das coisas. O detalhe é que as pessoas se esqueçem de fazer a sintese ( aglomeração ordenada das partes). Só depois de vc entender os detalhes vc pode modelar polimorficamente de forma que as duas classes Individuo e Empresa que implementam Pessoa possam ser usadas indestintamente como Clientes, Fornecedores, etc…

Y

Neste ponto especifico e apenas neste eu discordo do Sergio. O que acontece se amanha surgir um outro super ultra mega framework pra substituir o hibernate? Eu tenho que fazer modificacoes em todos os meus repositorios pra me adequar a ele. Repositorios fazem parte do dominio e devem mudar quando houver mudanca no dominio e nao por outro motivo (mudanca no framework de acesso). Regra basica de responsabilidade: uma classe deve ter uma e apenas uma razao para mudanca.

Eu nao vejo como uma obrigacao de uma boa arquitetura os DAOs quando vc tem o hibernate, mas nao acho que seja ridiculo.

Quanto ao velho problema de pessoa fisica e pessoa juridica vai outro velho conceito OO. Encapsule o que varia. Agora se varia muito nao faz sentido pertencerem a um mesmo conceito so pelo fato de ambas se chamarem pessoa.

S

YvGa:
sergiotaborda:

finalmente alguem que entendeu o problema. É isso mesmo. DAO com hibernate é rídiculo. Pessoa fisica e Juridica como herança de Pessoa é ridiculo. Acrescento também a modelagem de Cliente como herança de Pessoa.

Neste ponto especifico e apenas neste eu discordo do Sergio. O que acontece se amanha surgir um outro super ultra mega framework pra substituir o hibernate? Eu tenho que fazer modificacoes em todos os meus repositorios pra me adequar a ele. Repositorios fazem parte do dominio e devem mudar quando houver mudanca no dominio e nao por outro motivo (mudanca no framework de acesso). Regra basica de responsabilidade: uma classe deve ter uma e apenas uma razao para mudanca.

O ponto é : Hibernate é uma a implementação do padrão DomainStore. O DomainStore contém um DAO ( no hibernate chama-se dialetos). Logo, o DomainStore é “maior” que o DAO. Ao criar um DAO de hibernate vc está colocando o “maior” dentro do menor. Isso não faz sentido.

Quem usa Hibernate quer não se preocupar com o banco de dados. A menos que a sua aplicação vá comunica com outra tecnologia que não JDBC, então vc não precisa nunca mudar do hibernate. Em tese, vc poderia até criar um dialeto para XML ou qq outra tecnologia. O problema aí é prático porque o Hibernate é baseado no conceito de que se está comunicando via SQL com um JDBC.

Vc usa hibernate com DAO. Otimo. Vc acha que isso é uma vantagem para a hora que tiver que mudar de persistencia. Então o desafio é simples: construa um outro DAO com dados em memoria e tente usa com a sua aplicação. E veja quantas coisas vc tem que mudar além do DAO. Depois crie um DAO para um conjunto de arquivos XML (um por tabela) e veja quanto mudou. Vc vc não mexer uma virgula no codigo acima do DAO, otimo. Vc construiu um sistema de DAO muito desacoplado da persistencia.
Agora o outro lado da pergunta é: Quantas logicas de negocio vc tem no DAO que teve que reescrever nos dois novos daos ? Se vc não reescreveu nenhum, otimo. Vc fez um DAO desacoplado do dominio.

O ponto é: O seu DAO é desacoplado da API de persistencia E do dominio ?
Vc pode realmente mudar de DAO quanto quiser ?

A resposta provavelmente é não a alguma das questões. E por isso que usar DAO com hibernate é ridiculo. Vc está se enganando, achando que o fato de ter um objeto chamado XYZDAO o está ajudando. Não está.

J

Concordo com YvGa… criar um DAO do hibernate parece redundante, mas quando for trocar (se for) de framework de persistencia, então é bem mais simples se o Hibernate estiver somente no DAO… se for espalhado pela 100 classes de sua aplicação é mais complicado não?

Quanto ao foco do fórum, apesar de ler tudo, ainda não consigo sair do pensamento da arquitetura:


Cliente extends PessoaFísica extends Pessoa
Funcionário extends PessoaFísica extends Pessoa

Pessoa Jurídica extends Pessoa

Cliente tem muito atributos em comum com Funcionário, encapsulado em PessoaFísica, PARA NÃO PRECISAR REPETIR. Além, Cliente e Funcionário TÊM outros atributos totalmente diferentes, que justifica a separação das classes.

Pessoa Jurídica também compartilha atributos de Pessoa, mas possuem outros tbm diferentes. No caso PJ é meu fornecedor.
Lembrando que Pessoa dita não é “ser humano”, mas sim juridicamente.

Dito isto, como seria um mapeamento mais correto sobre isso? Alguém aí disse que seria legal uma classe para todos, o que mata os atributos que seria repetidos, mas e os atributos diferentes, como faz?? E a regra que diz que uma classe têm que ter todos os seus atributos pertinetes não existe mais??

Abstraindo o real para o lógico, PJ e PF são diferentes, o que não podem existir em uma única entidade. E para não precisarmos repetir atributos e métodos, abstraimos para uma classe Pessoa e extendemos em PF e PJ… não vejo outra solução.

Alguem pode esclarecer melhor?

jopss :stuck_out_tongue:

S

Só lhe digo que herança não foi feita para aproveitar campos. Isso é POG.
Herança é utilizada quando existe uma relação É-UM entre os objetos e não quando "TEM-OS-MESMO-CAMPOS"
Enquanto não entender isto, toda a conversa é inutil.

Não, não são diferentes. Se vc não vê isso é porque ainda não abstraiu o suficiente.

J

sim, falei de REPETIÇÃO para entendimento melhor, pois uma dos conceitos é a abstração. Além:

Cliente É-UMA PessoaFísica É-UMA Pessoa

oq poderia ser feito melhor ae?

S

jopss:
sim, falei de REPETIÇÃO para entendimento melhor, pois uma dos conceitos é a abstração. Além:

Cliente É-UMA PessoaFísica É-UMA Pessoa

oq poderia ser feito melhor ae?

Muitas coisas.
Cliente não é uma PessoaFisica porque tb pode ser uma PessoaJuridica. Se vc quer melhorar
vc pode dizer que Cliente é sempre uma PessoaJuridica que pode ser um Individuo, uma Empresa, uma Perfeitura, uma Fundação , etc… Vc está dividindo entre fisica e juridica, por vc está dividindo entre cpf e cnpj , mas perfeituras não têm cpf nem cnpj e mesmo assim podem ser clientes. Fundações idem.
Se vc gosta de limitar quem pode ser cliente, vá em frente, mas não é certo. :wink:

J

Somente para colocar lenha na fogueira.
Ainda bem que essa discussão sobre DAO não aflorou novamente, não porque aqui não é o tópico indicado, mas pq é esquisito, as pessoas não conseguem nem abstrair o ?paradigma? pessoa, cliente … e querem abstrair um DAO genérico suficiente para que em uma determinada fase da vida do projeto mude o framework de persistência. Bom a questão alem da já colocada pelo Taborda é: se hj na comunidade java existe dificuldade imensa para abstrair coisas cotidianas, pq alguém acha que vai conseguir abstrair algo tão mais complexo. Logo concordo com Taborda, usar DAO pensando em um dia trocar de framewk de persistência é perda de tempo, é melhor perdemos tempo em discutir coisas como pessoa, cliente e afins, pois existe mais confusão nesse tipo de implementação do que em um DAO que não faz sentido.
Quando comecei estudar POO, principalmente aqui no guj, li mto sobre DAO, alias, contem quantos tópicos sobre DAO existe aqui, hj graças a ajuda o Taborda enxergo que perdi mto tempo de leitura, e pior de programação pois tambem já tentei generalizar um DAO que continha o hibernate. Agora me pergunto, quantos outros conceitos estão sendo difundidos aqui em outros sites e que não fazem sentidos.
Sou programador Delphi e C#, a pouco tempo(1 ano) comecei a programar em java, escutei muitas coisas como ?programador Delphi são apertadores de parafusos ?.. ? ahh eu programo em java e sou o cara ? … ?ahh eu programo em java logo programo em POO?. Sim o guri começa a programar em java faz uns new alguma coisa, lê sobre DAO hirbernate e pronto acha que sabe td, vira um cético ignorante e fica difundindo coisas sem nexo. Desculpe meu desabafo mas vejo o mesmo numero de bobagens nos fóruns de delphi e java, a diferença é que em fóruns java existe mto mais pessoas que realmente sabem, e diga-se de passagem, são mto mais participativos.

Desculpe ter fugido do assunto, bom, se esse tópico pelo menos consegui-se deixar claro que começar a abstrair pessoa pelo cpf e pelo cnpj é ridículo eu já fico feliz.
Quando digo que pf e pj não existe, realmente estou me expressando mal, mas oq quero passar é que começamos abstrair através de outro ponto, e não pela mera diferença de campos como cpf e cnpj.

Agora vejamos a confusão, não conseguimos chegar em uma conclusão como seria melhor abstração de pessoa, cliente … e alguns querem discutir generalização sem fundamento de um DAO. Vamos concluir e chegar em um veredito sobre o assunto proposto pelo tópico em depois discutir o maldito DAO.

Acho q um grande contribuidor para essa confusão de pj, pessoa … são os exemplos didáticos, já li livros vários livros, alias quase todos exemplos de poo onde se apresenta o exemplo: PF herda pessoa e PJ herda Pessoa. Começa-se ensinar poo através de herança quando deveria-se começar por interface composição. Eu sou um hibrido desses livros e professores que tiveram a infelicidade de usar esse exemplo.

Então como idéia vamos começar pensar na idéia de cliente. Quem é o cliente oq ele faz, oq ele pode, que pode ser o cliente.
Daí vamos criar uma interface cliente e depois voltar para discussão pessoa e esquecer pf e seus atributos.

Criado 27 de dezembro de 2007
Ultima resposta 9 de abr. de 2008
Respostas 39
Participantes 12