Duvida O.O (Herança, Interface)

11 respostas
dooda

Buenas pessoal, para exercitar um pouco o java (estou aprendendo…), resolvi fazer
um pequeno mecanismo de persistencia, para tanto tenho:

* uma superClasse abastrata que representa as entidades com operações proprias
(creio que isso não é o mais correto, mas a questão não é essa agora)

public abstract class Entity implements Serializable{

	private DaoGeneric dao = null;
	
	public DaoGeneric getDaoGeneric(){
		if (dao==null) {
			dao = new DaoGeneric();
		}
		return dao;
	}
	
	public void insert() throws Exception{
		getDaoGeneric().insert(this);
	}
	public void update() throws Exception{
		getDaoGeneric().update(this);
	}
	public void delete() throws Exception{
		getDaoGeneric().delete(this);
	}
	public void findById() throws Exception{
		getDaoGeneric().findById(this);
	}
	
	public List<Entity> findByCriteria(String aCriteria) throws Exception{
		return getDaoGeneric().findByCriteria(this, aCriteria);		
	}
	
}

* Uma Interface IDao, para que o Dao Generico siga essas regras…

public interface IDao {
	void insert(Entity e) throws Exception;
	void update(Entity e) throws Exception;
	void delete(Entity e) throws Exception;
	void findById(Entity e) throws Exception;
	List<Entity> findByCriteria(Entity e, String aCriteria) throws Exception;				
}

* Meu Dao Generico que realiza as operações com o DB

public class DaoGeneric implements IDao {

	public void delete(Entity e) throws Exception {
	  //Implementar...
	}

	public void findById(Entity e) throws Exception {
	  //Implementar...
	}

	public void insert(Entity e) throws Exception {
	  //Implementar...
	}

	public void update(Entity e) throws Exception {
	  //Implementar...
	}

	public List<Entity> findByCriteria(Entity e, String aCriteria) {
	  //Implementar...
	}
}
  • E aí um Bean Cidade que extende a Entity normalmente…
public class Cidade extends Entity {

	private Integer id;
	private String cep;
	private String nome;

        //Get and Set omitidos...
}

* Com essa estrutura, posso utilizar facilmente da segunte forma:

public static void main(String[] args) {
		
		Cidade c = new Cidade();
		c.setCep("85950-000");
		c.setNome("Palotina");
		c.setId(1);

		try {

			//Cidade
			c.insert();
			c.update();
			c.delete();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

[color=red]Agora a dúvida:[/color]
Caso eu queira extender um Bean de Entity mas não quero permitir-lhe, por exemplo, a exclusão, como faço?

  • sim, foi muito código apenas para uma paergunta, mas conforme vo implementando, usarei os mesmos códigos para outras dúvidas…

:wink:

11 Respostas

tubiluki

acho que teria de sobreescrever os métodos da classe Entity, que você quer que não estejam disponiveis, para disparar uma exception ou algo do tipo.

mas acho que melhor mesmo era mudar essa estrutura ai.

peczenyj
Caso eu queira extender um Bean de Entity mas não quero permitir-lhe, por exemplo, a exclusão, como faço?

Seu problema poderia ser resolvido com interface/composição e não com herança.

interface X {
    void inclui(Object o);
}

class Entidade implements X{
    void inclui(Object o){}
    void exclui(Object o){}
}

class EntidadeQueNaoExclui  implements X{
    private Entidade e;
    public EntidadeQueNaoExclui(){ e = new Entidade();}
    void inclui(Object o){ e.inclui(o);}
}

Ou na sua interface X vc pode colocar o método exclui e na EntidadeQueNaoExclui vc pode
- não fazer nada
- lançar exception
- sorrir

kinow

Olá dooda, que tal?

Você tem uma Entity, que pelo que entendi representa uma entidade básica e essencial no seu sistema. Ela tem algumas operações básicas, como insert, update, etc…

Mas elas já estão implementadas … se você realmente precisa deixá-la implementada, isto é, o DaoGeneric com certeza realiza as operações básicas da Entity, OK. Senão, não implemente, desacople os objetos, separe a inteligência para recuperar um recuperar um DaoGeneric em uma classe para isso, e deixa na Entity apenas informação referente a ela.

Se sua Entity for um Pet, e você for utilizar o PetDao para as operações da Entity, por que então, o Pet teria um método getDaoGeneric?? :frowning:

Daí vejo duas soluções para sua dúvida, a primeira:

i) implemente os métodos somente lançando uma exceção de NotImplemented… desta maneira, toda chamada em uma entidade que não possui um método implementado, lançará uma exceção e você poderá tratá-la.

ii) transforme os métodos em abstract e, na classe que você não quiser que seja utilizado algum dos métodos, lance uma exceção NotImplemented.

Que tal?

Abraços,
Kinoshita

dooda

pois é, eu sei que sobrescrevendo já resolve…
mas eu pensava mesmo em “ocultar” a chamada do método…

:oops:

dooda

Então acho que uma maneira de eu mesmo não invocar esse método “sem querer”, achei uma pequena solução interessante sem mudar essa estrutura…

@Override
	@Deprecated
	public void delete() throws Exception {
		throw new Exception("bla bla bla...");
		//super.delete();
	}
alarangeiras

Concordo com a ideia da interface se implementado da seguinte maneira

interface PessoaView {
     public void inserir();
     public void alterar();
}

public class Pessoa implements PessoaView {
     public void inserir(){}
     public void alterar(){}
     public void excluir(){}
}

public class Principal {
     public static void main(String[] args) {
          PessoaView novaPessoa = new Pessoa();
          //Assim a variavel novaPessoa so tera acesso aos metodos implementados por PessoaView
          novaPessoa.inserir();
     }
}
sergiotaborda

Humm… findeByID deve receber um ID e retorna uma entidade, não receber uma entidade e não retornar nada…

Existem algumas alternativas:

  1. você sobreescreve o método na classe filha
  2. vc define todos os métodos de entity como final e usa annotations.
@Deletable(false)
class Cidade extends Entity{

}

A classe entity procura por essa anotações e dá exception quando alguem tentar usar o método correspondente
O padrão é permitir todas as operações.

peczenyj

Anotações…

Ainda não consigo pensar com Anotações :frowning:

dooda

como eu havia falado no começo, fiz a entity tratar as operações com o DB, e não era esse o problema, mas já que tocou no assunto, acredito que:

Por que deveria passar um Id, se ele proprio já possui? (ahhh, to usando anotações para o GenericDao)
então na pratica ficaria algo como…

Cidade c = new Cidade();
	c.setId(1);
	c.findById();

Como se fosse um load(); ou algo do tipo… e não usando argumentos para os métodos da classe entity…

sergiotaborda

dooda:

Por que deveria passar um Id, se ele proprio já possui? (ahhh, to usando anotações para o GenericDao)
então na pratica ficaria algo como…

Cidade c = new Cidade();
	c.setId(1);
	c.findById();

Como se fosse um load(); ou algo do tipo… e não usando argumentos para os métodos da classe entity…

Isso chama-se procura por semelhança ( findByTemplate) e não é prático.
Das duas uma, ajuste os nomes ou muda a API.

A sua solução tem um problema adicionar : carregamento mágico.
não é obvio que c.findByID() carega dos dados no c

A forma padrão seria ssim

Cidade c = Cidade.findByID(1);

muito mais simples de usar.
Contudo essa forma é impossivel usando herança como vc tem, então no seu caso particular seria melhor assim

Cidade c = new Cidade();
	c.setId(1);
	Cidade b  = c.findByTemplate();

ou 
        Cidade c = new Cidade();
	Cidade b = c.findById(1);

O retorno é muito importante porque deixa claro que ha uma inicialização do objeto.
E detalhe b != c tem que ser verdadeiro. Ou seja, o método não deve retornar o objeto que foi usado para o template da pesquisa
porque isso pode dar problemas durante a utilização dos objetos.

dooda

muito bem… :smiley:
Estou querendo entender todo esse conceito aí…

A principio não é tao facil, mas devagar vai encaixando, é que trabalho profissionalmente com Delphi…
Temos em um ERP em delphi essa mesma estrutura no mecanismo de persistencia com 275 tabelas tudo funciona muito bem. :oops:

Não estou querendo “imitar” ou “migrar” isso pro java, mas foi uma maneira associativa de implementar um problema como estudo de caso…

obrigado por enquanto… :slight_smile:

Criado 28 de maio de 2008
Ultima resposta 28 de mai. de 2008
Respostas 11
Participantes 6