Modelagem Pessoa Fisica/Pessoa Juridica

Estou com uma duvida sobre o modo de Modelar Pessoa - PessoaFisica - PessoaJuridica, eu sei q existe muitos Topicos sobre isso, e li varios, mas ainda nao consegui entender, vai minha duvida:

Estou modelando um sistema, e tenho os seguintes tipos:

Cliente, que pode ser PessoaFisica ou Pessoa Juridica
Fornecedor, pode ser somente PessoaJuridica
Funcionario,pode ser somente PessoaFisica
Transportadora, que pode ser PessoaFisica ou Pessoa Juridica

eu estou pensando em fazer o seguinte

Criar uma classe abstrata Pessoa, Criar uma Classe PessoaFisica que extende Pessoa e PessoaJuridica que extende Pessoa

Agora que complica, como faco a relacao de Cliente, a solução q eu achei seria o seguinte

Fazer uma composicao , uma Classe Cliente compoe Pessoa e possue um atributo Pessoa, q eu vou instanciar como PessoaFisaca ou juridica, faco o mesmo para Transportadoss, mas não sei se esta certo isso, me parece meio Gambiarra…

se alguem puder me ajudar a esclaresser esse problema ficaria muito grato…

Aguardo resposta e a compreencao por eu ter criado um tópico a mais sobre esse assunto, mais é q eu nao estou conseguindo enchergar a solucao…heheheheh

Obrigado!!!

Caloro, após ter criado a classe PessoaFisica, PessoaJuridica, etc…

Pense bem :roll: , heranca multipla NAO existe no java. Mas isso pode ser contornado com o uso de interfaces !
Com essa dica você resolve o problema do cliente !?

---------------------Editado------------------------

Ah, esqueci de comentar a solução que você propos…
Ao criar uma classe Cliente que possui um atributo do tipo Pessoa, você não está dizendo que Cliente é uma Pessoa…
O enunciado quer que você instancialize um cliente ou como PessoaFisica ou como PessoaJuridida …

Att,
Renan

Renan, por isso q eu estava achando estranho usar um atributo pessoa. Mas com essa solucao da interface q vc disse, eu teria q criar duas interface: PessoaFisica e Pessoa Juridica, ambas com extend Pessoa(q continua sendo classe abstrata, certo?) e no cliente eu teria alguma coisa assim??

[code]public class Cliente implements PessoaFisica,PessoaJuridica{

}[/code]

seria essa a solucao mais correta de acordo com sua opiniao?, é q eu sou meio novo em java, por isso estou perguntando, heheh…

Depende caloro.
você pode herdar de uma classe e implementar interfaces ao mesmo tempo…

Eu sempre vejo o que aproveitará mais código e será de mais utilidade para a situação.

Faça de uma forma que escreverá menos código, aumente a manutenabilidade, etc etc…
Use e abuse de OO e aproveite dessa caracteristica do java, a interface.

Isso gera bastante discussão. Há quem diga para se programar voltado à interfaces, outros nao… Existem vários tópicos sobre isso por aqui.

Att,

Renan

valew Renan, vou pesquisar sobre interface e ver o q é melhor, obrigado mesmo ela ajuda…agora ja sei o caminho da minha solução…heheh

Um problema que vejo com o uso de interfaces é que você na consegue fazer um “ou exclusivo” da herança. Assim, o cliente sempre será PessoaFisica E PessoaJuridica. Na modelagem do dominio isso meio que começa conflitante, né? Como explicar pro cliente (do sistema) que o entregador dele é PF e PJ ao mesmo tempo?

Apesar de mais código ser escrito, nao seria melhor compor uma pessoa fisica ou juridica com as informações das “especializações”? Assim… Como uma Pessoa (fisica ou juridica) pode ser cliente E transportadora, seria interessante que a entidade desse suporte a isso. Caso contrario, eu teria duas pessoas no sistema com uma mesma identificação (CNPJ), o que seria um estado inválido do sistema.

Intaum nicholas.bittencourt, qto ao problema do “ou exclusivo”, eu li alguma coisa de heranca disjunta, só q eu teria q criar uma classe ClientePessoaFisica e outra ClientePessoaJuridica, e o mesmo para tranportados, assim eu usaria uma “ou” outra, mas assim eu teria uma classe usada as vezes sim as vezes nao, nao sei c seria a solucao mais correta…

A solução depende de mais informações do negócio.

O estado muda com freqüência (PJ vira PF, depois muda para PJ/PF)? Existem regras específicas e complexas para cada tipo (PF, PJ e PJ/PF)?

Uma possível solução (GOF), para não duplicar código, em casos de muitas regras específicas e algumas compartilhadas, seria:

A menos que você vá usar a superclasse Pessoa em alguma chamada polimórfica faça a composição. Herança é sadia quando e criam hierarquias, quando se está apenas reutilizando código pode acabar criando relações esquisitas, especialmente sem herança múltipla.

Sim, claro, herança apenas como artifício de reuso complica mais que ajuda (trocar herança por composição).

Dependendo do negócio, que foi pouco explorado neste caso, pode existir uma herança honesta mesmo sem polimorfismo (apenas herdando responsabilidades), eu acredito.

Estou defendendo na verdade uma maior exploração do negócio.

Se você não vai ter poliorfismo para quê herança?

Acho interessante trabalhar com tipos mais abstratos, mesmo sem polimorfismo, no caso de heranças aderentes aos conceitos do negócio. Agrupando responsabilidades comuns.

Nao entendi. Voce pode ter tipos bem abstratos sem hranca (mesmo com a tipagem estatica meia-boca de Java), tem um exemplo?

Eu acho uma entidade “Pessoa” uma abstração muito crua e até mesmo sem sentido para a hierarquia proposta.
Veja no sebrae a seguinte distinção:

O que é pessoa física e pessoa jurídica?

Uma Pessoa Jurídica NÃO é da mesma hierarquia NATURAL de pessoa, é uma abstração que vai além disso. Fazer uma hieraquia dessa é gambiarra para aproveitar atributos. Uma pessoa jurídica pode ser uma empresa ou uma associação/companhia e não necessariamente uma Pessoa.

Um exemplo melhor: Cliente; ClienteCorporativo; ClientePessoa; (Uma herança honesta, aderente ao negócio)

Operação: obterCassificação (calculada em função da data de adesão do cliente e do endereço; data e endereço são atributos de Cliente)

A implementação desta Operação seria um método na classe mais abstrata. (Não teríamos mais métodos nas outras classes para essa operação, pois o comportamento é idêntico)

Eu estava considerando este caso como uma herança sem polimorfismo, pois o método para essa operação não será escolhido em tempo de execução (sem polimorfismo, só existe um método para essa Operação)

OK, talvez conceito de polimorfismo esteja impreciso. Podemos considerar polimorfismo, mesmo com apenas um método para a Operação?

Uma chamada polimórfica é uma chamada que se comporta diferente com o objetivo. Em Java isso quer dizer que se eu mandar a mesma mensagem para diversos objetos eles podem reair de maneira diferente. No sistema de tipos de Java “a mesma mensagem” envolve ter uma classe ou interface em comum.

Como conversamos via IM, herança sem polimorfismo é possível, por vezes justificável, mas é mais uma limitação que leva a um design ruim. Quandos e tem herança sem chamadas polimórficas significa que o sistema em si não conhece a classe pai, possivelmente esta não faz parte do domínio. A classe pai é usada apenas como unidade de reuso, e isso pode causar problemas porque acaba-se criando uma hierarquia artificial. Nesse caso eu sugiro refatorar o comportamento comum em uma classe e usar coposição.

[editado] … o que tinha escrito ficou redundante relendo o ultimo post do Shoes.