tenho dúvidas de como abstrair num sistema de vendas essas classes
Pessoa
Empresa
Cliente
Vendedor
Fornecedor
no mundo real, um Cliente pode ser uma Empresa ou pode ser uma Pessoa
e também, um Fornecedor pode ser uma Empresa ou pode ser uma Pessoa
abstraindo em OO um Cliente poderia ser uma superclasse e as classes Pessoa e Empresa uma subclasse e por meio do Polimorfismo, uma variável de instância de Superclasse Cliente poderia armazenar o endereço de uma instância das Subclasses Empresa ou Pessoa
Entretanto, como eu faço para que um Fornecedor(super) possa ser também uma Empresa(sub) ou uma Pessoa(sub), sendo que Pessoa e Empresa não são Subclasses de Fornecedor?
ou tá tudo errado,
Cliente, Fornecedor, Vendedor são uma Pessoa
se o Java aceitasse Herança Múltipla aí seria fácil
no Polimorfismo uma variável de instância só pode receber endereço de uma instância de Subclasse
ou essa Abstração, Cliente(Superclasse) e Empresa(sub) e Pessoa(sub) é descabida?
Priorise a composição ao invés da herança!
Isso não é ideia minha não… é regra de padrões de projeto!
O que caracteriza uma pessoa física ou juridica?
As duas são pessoas, só que uma tem alguns atributos diferentes! Uma tem CPF outra CNPJ. Então podemos ter Pessoa->PessoaFisica e Pessoa->PessoaJuridica!
E o cliente? O cliente é uma pessoa? Não será que o Cliente é o Cliente e pronto? Ele não seria o Cliente e teria um cadastro de pessoa juridica ou um cadastro de pessoa física?
Então Poderiâmos ter Cliente.pessoa!
Para não ter que fazer uma verificação de tipos, a classe Pessoa poderia ser abstrata e ter um método abstrato que retorna-se uma enumaração TipoPessoa que seria implementado nas classes PessoaFisica e PessoaJuridica retornando respectivamente tipoPessoa.FISICA e tipoPessoa.JURIDICA ai é só fazer a conversão para o tipo apropriado quando necessário!
if(cliente.pessoa instanceof PessoaFisica)
//O cliente é uma pessoa física
else
if(cliente.pessoa instanceof PessoaJuridica)
//O cliente é uma empresa (Pessoa jurídica)
if(cliente.pessoa instanceof PessoaFisica)
//O cliente é uma pessoa física
else
if(cliente.pessoa instanceof PessoaJuridica)
//O cliente é uma empresa (Pessoa jurídica)
[/quote]
Na verdade esta prática não é recomendada.
[quote]Effective C++, Scott Meyers :
"Anytime you find yourself writing code of the form “if the object is of type T1, then do something, but if it’s of type T2, then do something else,” slap yourself. [/quote]
Mas comparar um atributo do objeto que diz de que tipo ele é e utilizar o instanceof não seria mais ou menos o mesmo algoritmo? Ou utilizando um enum para definir de qual o sub-tipo do objeto é mais recomendavel?
[edit]Só me referia a casos bem específicos em que fosse necessária a conversão para o sub-tipo, não sendo viável o uso do polimorfismo… Acho que o x@ndy também se referia a os mesmos casos [/edit]
[quote=drigo.angelo]Valew eros.stein, não sabia disso :oops:
Mas comparar um atributo do objeto que diz de que tipo ele é e utilizar o instanceof não seria mais ou menos o mesmo algoritmo? Ou utilizando um enum para definir de qual o sub-tipo do objeto é mais recomendavel?
[edit]Só me referia a casos bem específicos em que fosse necessária a conversão para o sub-tipo, não sendo viável o uso do polimorfismo… Acho que o x@ndy também se referia a os mesmos casos [/edit][/quote]
Sem problema, eu não sei um monte de coisa =D estamos aqui pra trocar conhecimento.
O uso do instanceof não é proibido. Ele deve apenas ser usado com cautela. (beba com moderação =P)
Sempre que for possível usar polimorfismo, deve-se utilizá-lo! (ainda não vi uma fonte confiável que dissesse o contrário e mesmo se encontrasse seria uma contra inúmeras que dizem o contrário)
Bom, a primeira questão e mais importante é baseada nos padrões de projeto. A boa prática de programação OO diz que instanceof deve ser evitado.
Uma das “inúmeras” fontes que falei: http://www.artima.com/interfacedesign/PreferPoly.html
A segunda questão seria a performance, o custo de execução de um instanceof é caro. Hoje com PCs super rápidos e JVMs avançadas essa questão nem é tão discutida mais, mas já foi palco de grandes debates.
[quote]Modern JVM/JIC compilers have removed the performance hit of most of the traditionally “slow” operations, including instanceof, exception handling, reflection, etc.
As Donald Knuth wrote, “We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.” The performance of instanceof probably won’t be an issue, so don’t waste your time coming up with exotic workarounds until you’re sure that’s the problem.[/quote]
É isso. Esse assunto já foi muito discutido anos atrás, se tiver interesse pesquise mais sobre o assunto.
Tenho certeza que vai encontrar muitas fontes interessantes.
A única coisa que eu teria cuidado com essa arquitetura do x@ndy é com a similaridade entre pj e pf.
Na prática há tantas diferenças, que fica quase inviável tratar como a mesma coisa sem ifs.
Por exemplo:
PF tem um nome e PJ nome fantasia e razão social.
Dependendo da hora e lugar para o PJ é interessar usar como nome um atributo ou outro.
Outro fator que deve levar em consideração é que uma Cliente pode ser também Fornecedor.
Eu considero que Cliente, Fornecedor são relações comerciais que existem entre a dona do sistema e um PF ou PJ.