Ajuda com a classe Cliente usando herança

[quote=tmvolpato]@Mendes,
estou implementando essa sua ideia de generics

@Machado

machado nesse seu modelo você consegue dizer tranquilamente que tipo é o cliente
na classe produto por exemplo

[/quote]
Tanto quanto o uso de generics, neste caso, eu posso verificar com instanceof…

[code]
public class Cliente {
private IPessoa iPessoa;

public void setiPessoa(IPessoa iPessoa) {
	this.iPessoa = iPessoa;
}

public IPessoa getiPessoa() {
	return iPessoa;
}

private String verificaPessoa(IPessoa ipes){
	if(ipes instanceof PessoaFisica){
		return "PF";
	}else {
		return "PJ";
	}
}

public static void main(String[] args) {
	Cliente c = new Cliente();
	c.setiPessoa(new PessoaFisica());
	System.out.println(c.verificaPessoa(c.getiPessoa()));
	c.setiPessoa(new PessoaJuridica());
	System.out.println(c.verificaPessoa(c.getiPessoa()));
}

}[/code]

[quote=drsmachado][quote=tmvolpato]@Mendes,
estou implementando essa sua ideia de generics

@Machado

machado nesse seu modelo você consegue dizer tranquilamente que tipo é o cliente
na classe produto por exemplo

[/quote]
Tanto quanto o uso de generics, neste caso, eu posso verificar com instanceof…

[code]
public class Cliente {
private IPessoa iPessoa;

public void setiPessoa(IPessoa iPessoa) {
	this.iPessoa = iPessoa;
}

public IPessoa getiPessoa() {
	return iPessoa;
}

private String verificaPessoa(IPessoa ipes){
	if(ipes instanceof PessoaFisica){
		return "PF";
	}else {
		return "PJ";
	}
}

public static void main(String[] args) {
	Cliente c = new Cliente();
	c.setiPessoa(new PessoaFisica());
	System.out.println(c.verificaPessoa(c.getiPessoa()));
	c.setiPessoa(new PessoaJuridica());
	System.out.println(c.verificaPessoa(c.getiPessoa()));
}

}[/code][/quote]

estou testando aqui

valeu pela ajuda até o momento
@Machado
@Mendes

[quote=tmvolpato][quote=rmendes08][quote=tmvolpato]Mendes como eu disse ali em cima

ele pode ser os dois mas não ao mesmo tempo
essa decisão seria tomada no cadastro do cliente[/quote]

Você pode usar Generics na sua classe Cliente, assim você parametriza o tipo do Cliente:

class Cliente<T extends Pessoa>{
   private T pessoa;

   public T getPessoa(){
   }
}

[/quote]

Dessa maneira

eu consigo indicar apenas uma classe Fisica ou Juridica dessa maneira certo?

Foi como ele disse la em cima eu precisaria de uma herança múltipla "Mas isso não existe em java"
para poder estender as duas classes.

é complicado esse assunto
[/quote]

Nesse caso, você decide o tipo da pessoa no momento de declarar a variável:

   Cliente<PessoaFisica> cpf = new Cliente<>();
   Cliente<PessoaJuridica> cpj = new Cliente<>();

[quote=drsmachado]Camarada, não enxergo. Primeiro que esta regra de um cliente poder ser PJ e PF está, no MEU ponto de vista, errada.
Afinal, o cadastro será feito por CPF/CNPJ, não? Um PF associado a um CPF, um PJ a um CNPJ.
Além do mais, um Cliente podendo ser PJ e PF ao mesmo tempo, requeriria herança múltipla. Inexiste no java.
Há meios sim, de se obter um objeto filho a partir de uma instância da classe Pai, utilizando cast

Pessoa p = new PessoaFisica();
PessoaFisica pf = (PessoaFisica) p;

Plenamente possivel.[/quote]

Desse jeito eu enxergo os atributos, mas como vou salvar eles na minha classe Cliente

lembrando que individual so repassa os atributos pq ela é uma superclass

IPessoa é ruim demais! Eu não gosto… Nomenclatura ultrapassada. Quando eu vejo alguém usando essa nomenclatura desconfio na hora… Isso é pré-histórico e me lembra EJB1.

A questão principal é que não existe uma pessoa que não seja PessoaFísica ou PessoaJurídica, certo? Em outras palavras vc nunca vai instanciar Pessoa, mas apenas PessoaJuridica e PessoaFisica, certo? Pessoa então é apenas uma ESPECIFICACAO e não uma IMPLEMENTACAO.

Se esse for o caso então vc tem:

public interface Pessoa {

}
public abstract class AbstractPessoa implements Pessoa {

}
public class PessoaFisica extends AbstractPessoa {

}

public class PessoaJuridica extends AbstractPessoa {

}

Qualquer coisa diferente disso está errado. :slight_smile:

OBS: A class AbstractPessoa é opcional mais recomendável.

O código abaixo está errado:

[quote] private String verificaPessoa(IPessoa ipes){ if(ipes instanceof PessoaFisica){ return "PF"; }else { return "PJ"; } } [/quote]

Tem que usar polimorfismo sempre. If para polimorfismo é um erro primário que todos nós já fizemos. O negócio é fazer uam vez depois nunca mais.

Polimorfismo correto não admite qualquer IF.

[quote=saoj]IPessoa é ruim demais! Eu não gosto…

A questão principal é que não existe uma pessoa que não seja PessoaFísica ou PessoaJurídica, certo? Em outras palavras vc nunca vai instanciar Pessoa, mas apenas PessoaJuridica e PessoaFisica, certo? Pessoa então é apenas uma ESPECIFICACAO e não uma IMPLEMENTACAO.

Se esse for o caso então vc tem:

public interface Pessoa {

}
public abstract class AbstractPessoa implements Pessoa {

}
public class PessoaFisica extends AbstractPessoa {

}

public class PessoaJuridica extends AbstractPessoa {

}

Qualquer coisa diferente disso está errado. :slight_smile:

OBS: A class AbstractPessoa é opcional mais recomendável.

O código abaixo está errado:

[quote] private String verificaPessoa(IPessoa ipes){ if(ipes instanceof PessoaFisica){ return "PF"; }else { return "PJ"; } } [/quote]

Tem que usar polimorfismo sempre. If para polimorfismo é um erro primário que todos nós já fizemos. O negócio é fazer uam vez depois nunca mais.

[/quote]

Onde entraria Cliente ai ?

o problema esta ai, o cliente pode ser os 2 não ao mesmo tempo

O cliente vai CONTER (composicao) uma Pessoa.

E se vc quiser/precisar vc tb pode fazer o client SER uma pessoa, implementando Pessoa e delegando.

Qualquer coisa diferente disso está errado.

Assim:


public class Client implements Pessoa {

    private final Pessoa p;

    public Client(Pessoa p) {
       this.p = p;
   }

   // implementa os métodos de Pessoa e delega para p
}

Esse é o PATTERN decorator, o único que serve para alguma coisa. O resto é balela. Agora use esse pattern demais e vc fica com um sistema no estilo boneca-russa que ninguém entende. É para usar com muita parcimônia. Se vc está usando muito esse pattern significa que vc está complicando o simples. Por exemplo: Vc realmente precisa de dois objetos, Cliente e Pessoa !!!??? Não pode ser um só? Vc acabou de fazer o que 95% dos programadores fazem. Criou complexidade desnecessária para encher a boca e dizer: EU USEI O PATTERN DECORATOR !

@saoj

Pensei a mesma coisa tratar cliente como Pessoa

mas nesse seu exemplo como trataria Cliente

[quote=tmvolpato]
@saoj

Pensei a mesma coisa tratar cliente como Pessoa

mas nesse seu exemplo como trataria Cliente[/quote]

Leia isso que eu editei:

Não entendi a sua pergunta. Cliente é Cliente AND Cliente é Pessoa. Claro que Pessoa não é Cliente.

Conclusão: Vc introduziu complexidade no seu sistema. Para tudo e veja se não pode fazer um merge de Pessoa e Cliente numa classe só. Vai simplificar o seu sistema bastante.

Please delete (post duplicado)

[quote=saoj]IPessoa é ruim demais! Eu não gosto… Nomenclatura ultrapassada. Quando eu vejo alguém usando essa nomenclatura desconfio na hora… Isso é pré-histórico e me lembra EJB1.
[/quote]
Por isso eu coloquei isto no código

//IPessoa -- não use I antes de uma interface, neste caso, é um exemplo apenas.  
public interface IPessoa{  

[quote=saoj]
O código abaixo está errado:

[quote] private String verificaPessoa(IPessoa ipes){ if(ipes instanceof PessoaFisica){ return "PF"; }else { return "PJ"; } } [/quote]

Tem que usar polimorfismo sempre. If para polimorfismo é um erro primário que todos nós já fizemos. O negócio é fazer uam vez depois nunca mais.

Polimorfismo correto não admite qualquer IF.[/quote]
Concordo plenamente.

Saoj,

Eu estou usando herança e tratando cliente como pessoa
so vou ter acesso aos atributos do pai
e não das filhas, se eu estende a classe Pessoa

como eu trataria isso

Você acha um erro trabalhar com herança nessa parte?

[quote=saoj]O cliente vai CONTER (composicao) uma Pessoa.

E se vc quiser/precisar vc tb pode fazer o client SER uma pessoa, implementando Pessoa e delegando.

Qualquer coisa diferente disso está errado.

Assim:


public class Client implements Pessoa {

    private final Pessoa p;

    public Client(Pessoa p) {
       this.p = p;
   }

   // implementa os métodos de Pessoa e delega para p
}

Esse é o PATTERN decorator, o único que serve para alguma coisa. O resto é balela. Agora use esse pattern demais e vc fica com um sistema no estilo boneca-russa que ninguém entende. É para usar com muita parcimônia. Se vc está usando muito esse pattern significa que vc está complicando o simples. Por exemplo: Vc realmente precisa de dois objetos, Cliente e Pessoa !!!??? Não pode ser um só? Vc acabou de fazer o que 95% dos programadores fazem. Criou complexidade desnecessária para encher a boca e dizer: EU USEI O PATTERN DECORATOR ![/quote]

Posta o código, por favor. Descrever código e arquitetura com palavras é conversa de maluco.

Classe Pessoa

@Entity
@Table(name="PERSON")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="PERSON_TYPE" , discriminatorType=DiscriminatorType.STRING)
public abstract class Person implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Basic(optional=false)
	private Long id;
    
    @OneToOne(mappedBy="person",fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private Address address;
    
    @OneToOne(mappedBy="person",fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private Login login;
.
.
.

Classe Pessoa Fisica

@MappedSuperclass
public class Individual extends Person{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@NotNull
	@NotEmpty
	@Column(name="NAME", length=100, nullable=false)
	private String name;
	
	@NotNull
	@NotEmpty
	@Column(name="LAST_NAME", length=100, nullable=false)
	private String lastName;
	
	@NotNull
	@NotEmpty
	@Column(name="CPF")
	private String cpf;

Classe Pessoa Juridica

@MappedSuperclass
public class Company extends Person implements Serializable{

	private static final long serialVersionUID = 1L;
	
	
	@NotNull
	@NotEmpty
	@Column(name="FOUNDATION_OF_DATE",length=10,nullable=false)
	private Date foundationOfDate;
	
	@NotNull
	@NotEmpty
	@Column(name="CTR", unique=true,length=15,nullable=false)
	private String ctr;
	
	@NotNull
	@NotEmpty
	@Column(name="CNPJ", unique=true,length=15,nullable=false)
	private String cnpj;
	

A classe Cliente eu nao tenho nada pq estou procurando uma solução para implementar ela nesse modelo que estou passando

[quote=saoj][quote=tmvolpato]
Saoj,

Eu estou usando herança e implementando Pessoa
so vou ter acesso aos atributos do pai
e não das filhas

como eu trataria isso

Você acha um erro trabalhar com herança nesse modelo por exemplo?
[/quote]

Posta o código, por favor. Descrever código e arquitetura com palavras é conversa de maluco.[/quote]

Dois problemas graves:

  1. Você está usando a porcaria do Hibernate. Evite a todo o custo. Veja como fica feio o seu beanzinho cheio daquelas anotacões absurdas. Leia esse thread inteiro e depois olha o MentaBean. Uma explicacao mais simplificada do MentaBean está aqui: http://www.mentaframework.org/mtw/Page/ORM/mentawai-orm-e-sql-builder

  2. Person tem que ser INTERFACE e nunca uma classe Abstrata. Espero que não seja o maravilhoso Hibernate que está te obrigando a fazer isso. Vc tem que usar aquele esquema de interface mais classes abstratas que eu postei. Vc já viu como as Collections do Java foram feitas?

A solucao do Cliente é aquela que eu postei.

Já no banco de dados tu vai ter duas tabelas. Uma para guardar os dados de PessoasJuridicas e outra para guardar os dados da pessoa física. E vc pode carregar todos os tipos de clientes ao mesmo tempo fazendo um JOIN em ambas as tabelas porque será garantido que um cliente não terá ambos.

AGORA TENTA ORGANIZAR ESSA ZONA COM AS ANOTACOES DO HIBERNATE ???

Hibernate cria um problema maior e não soluciona nada. Faca isso na mão com o bom e velho SQL. Banco-de-dados não dá para “abstrair” como o Hibernate tenta fazer. É uma insanidade e uma atente contra o principio KISS.

O único jeito correto de abstrair o banco-de-dados é usando DAOs e um query-builder com um mapeamento bem simples tipo o MentaBean faz. Inventar mágica e anotacoes malucas como o Hibernate faz é insanidade.

É aprender espanhol em cima de ingles para falar ingles melhor.

Valeu pela ajuda…

vou fazer as mudanças aqui
Deu pra ter uma outra visão agora…

Obrigado!!

duvida aqui

ao implementar a interface Pessoa em Cliente
vou obter todos os atributos da classe Fisica e juridica
seria isso o correto? ou teria outra maneira?

[quote=tmvolpato]duvida aqui
ao implementar a interface Pessoa em Cliente
vou obter todos os atributos da classe Fisica e juridica
seria isso o correto? ou teria outra maneira?
[/quote]

Não entendi. O que vc falou não faz sentido.

Quando o Cliente implementa Pessoa ele vai ter que RECEBER uma Pessoa no construtor, que pode ser qualquer uma.

Daí ele vai DELEGAR todos os métodos de pessoa para esse objeto que ele recebe no construtor. O famoso e infame DECORATOR pattern.

Vc diz que PessoaJuridica e PessoaFisica não possuem uma interface comum ??? Aí ferrou !!! Esquece tudo que eu falei então. :frowning: :slight_smile:

Agora fiquei vendido no lance. Eventualmente vc vai ter que fazer um casting da Pessoa para PessoaJuridica ou PessoaFisica.

Acho que o melhor é ter interface Cliente e ClienteFisico e ClienteJuridico. Não dá para ter só um Cliente assim como não dá para ter só uma Pessoa.

O ideal é não complicar e fazer um merge do Cliente e da Pessoa num objeto só !!!

Peco ajuda para os estudantes,. Agora não sei o que é melhor. :slight_smile:

complicado msm
eu comecei a seguir suas dicas e cai nesse problema

da interface pessoa ter todos os atributos de Física e Jurídica
e cliente implementando ela seria obrigatório implementar todos

esse tbm não seria um cenário ideal concorda @SaoJ

tbm peço ajuda