Interface e static (não é possivel obrigar uma classe ter 1 método estatic ?)

13 respostas
Lavieri

tava afim de fazer 1 classe X que assina uma interface Y ser obrigada a implementar 1 método statico ja tentei de diversar formas mais ta dificil…

O objetivo é + ou - assim

public interface Entidade { public static IValidador getValidador(); }

public class Pessoa implements Entidade { public static IValidador getValidador() { return validador; //variavel estatica } //... }

mais não consigo obrigar as classes que assinam Entidade a ter um método estatico para retornar o validador.

precisava disso, pra não ter q fazer uma instancia para pegar o validador =/

Alguem sabe alguma forma de fazer ?

13 Respostas

gilmaslima

Você não pode ter métodos estáticos em interfaces, todos os métodos de interface são public e abstract independente de terem esses modificadores, mas as variaveis de interface são todas public static final

Você poderia ter uma interface mais ou menos assim

public interface Entidade {  
    public static final IValidador validador = algumaClasse.metodoRetornaIValidator();      
    public abstract IValidador getValidador();  
 }

…e na classe que fosse implementar a interface você seria obrigado a implementar o método e teria acesso a variavel validador

espero ter ajudado!

sobreira

Algumas observações:

Você não pode declarar os métodos de interface como estáticos Eles implicitamente são publicos e abstratos e nada além disso. Já váriaveis declaradas na interface serão sempre publicas, estáticas e finais.

Ao implementar a interface numa classe, estas características permanecem verdadeiras.

Um detalhe importante: se você redeclarar uma váriável da interface numa classe que implemente esta interface, você estará ocultando a variável da interface.

Com base nestas dicas observe seu código novamente e veja onde está errando. Aconselho-o a dar uma olhada na seção Artigos aqui do site que tem um material muito bom sobre interfaces.

[]s e boa sorte!

rubinelli

Se você não quer instanciar um novo objeto cada vez que for usar um validador, use um singleton.

Lavieri

Bom vou tentar explicar o q quero...

Pra toda entidade que eu fizer / implementar eu sou obrigado a criar 1 outra classe... Validador desta interface....
queria amarrar isso, para não ter falhas, obrigado quem implemetasse a Interface Entidade a ter o validador...

Mas o fato é que para fazer isso, tenho q criar um método não estatico o que não é bom, pois não é preciso instanciar a entidade para acessar seu validor...

Para exemplificar melhor...

public class Pessoa implements IEntidade {
     private static Validador<Pessoa> validador;
     public static Validador<Pessoa> getValidador() {
             if (validador== null) validador = new ValidadorPessoa();
             return validador;
     }
     
     private Integer id;
     private String nome;
     private String cpf;
     //...
     public Integer getId() { return id; }
     public void setId(Integer id) { this.id = id; }
     //... restante dos métodos getters e setters
}

Onde a classe ValidadorPessoa [color=violet]implements [/color]Validador<Pessoa>

public interface Validador<T extends IEntidade> {
	//Métodos que testam sem retornar exceções.
	public boolean isValidoAdd(T entidade);
	public boolean isValidoRemove(T entidade);
	public boolean isValidoReplace(T entidade);
	public boolean isValidoRetrive(T entidade);

	//Métodos que testam e retorna a exceção referente ao problema.
	public void validarAdd(T entidade) throws EntidadeException;
	public void validarRemove(T entidade) throws EntidadeException;
	public void validarReplace(T entidade) throws EntidadeException;
	public void validarRetrive(T entidade) throws EntidadeException;

	public Class<T> getEntidadeClasse();
}

............................

O que eu keria era garantir que quem fizesse uma IEntidade fizesse também um método static do tipo

public static Validador<T extends IEntidade> getValidador();

sedo assim eu teria certeza que, se Cidade implementa IEntidade, então eu posso fazer

Cidade.getValidador()
de forma estatica, quero amarrar, pra forçar alguem que crie uma IEntidade que faça também o seu validador.

tem como fazer isso ??

hvivox

Assim se vc quiser utilizar o static vc tem que esquecer as interfaces esse é o lance!

da uma olhada nisso! blz

http://www.guj.com.br/posts/list/54845.java

Marky.Vasconcelos

Acho que usando o padrão Factory voce consegueria resolver.

T

Isso foi uma escolha dos definidores da linguagem; há uma solicitação de mudança (RFE) no site da Sun; talvez se você votar nela o pessoal acabe considerando isso.

Bug ID: 4093687 - Extension of ‘Interface’ definition to include class (static) methods.

Lavieri

Não factory não resolve, o meu problema é no desenvolvimento ...

Digamos que eu precise ter 1 objeto persistente Livro, então eu crio o livro... porem eu não crio o objeto ValidadorLivro extends Validador<Livro>

o que vai acontecer é... quando alguem pegar o repositorio e tentar usar 1 comando básico....

Livro livro1 = new Livro();
livro1.setTitulo("");
livro1.setAutor("11123231");

RepositorioEntidade rep = Repositorios.getEntidadeRepositorio(); ...
rep.add(livro1);

isso vai gerar 1 erro.... pq rep.add(livro1), chama primeiro um objeto

Validador<Livro> validador = Livro.getValidador();
validador.validarAdd(livro1);

pra saber se é permitido adcionar livro sem titulo e com o nome de autor cheio de números, o que não é permetido...

ai está a falha, quando se tentar fazer Livro.getValidador(); isso não vai estar implementado, gerando um erro em tempo de execução... e eu kero amarrar isso no projeto...

.........

Obrigado ai a todos, to vendo que vou esperar essa requisição ai que o Thingol mando ^^

rep

Marky.Vasconcelos

Entao voce poderia ter uma classe static que mapeia um Validator para uma Class<?> e naquele chamado:

Validador<Livro> validador = Livro.getValidador();   
validador.validarAdd(livro1);

Ficaria algo como

Validador<Livro> validador = validadores.getValidador(Livro.class);
validador.validarAdd(livro1);
Lavieri

Mark_Ameba:
Entao voce poderia ter uma classe static que mapeia um Validator para uma Class<?> e naquele chamado:

Validador<Livro> validador = Livro.getValidador();   
validador.validarAdd(livro1);

Ficaria algo como

Validador<Livro> validador = validadores.getValidador(Livro.class); validador.validarAdd(livro1);

sim, eu tenho os repositorios… mais a questão… quem me garante que existe o validador ??? queria amarrar isso na assinatura de uma Entidade

na interface IEntidae, queria obrigar o cara a definir isso, esse validador, de forma a não existir problemas…

Alguem pode esquecer de fazer o validador e fazer bug no sistema.

Marky.Vasconcelos

Mesmo o método sendo estático o cara esta sujeito a implementar

public static Validador getValidador(){
return null;
}
L

Quando não se consegue as respostas corretas, é porque está se fazendo as perguntas erradas.

Conheço duas soluções diferentes para a validação que não involve o seu mecanismo (até porque, como você mesmo percebeu, existem “buracos”). Portanto jogue sua idéia no lixo e considere uma das duas possibilidades minhas:

  1. Não reinvente a roda. Usar Hibernate Validator, e você nem precisa do Hibernate “Core” pra usá-lo. Todas as validações são indicadas por anotações da biblioteca, e você pode ainda criar novas. E também existe uma API própria e genérica para a validação. Consulte a documentação.

  2. Falhe cedo e falhe sempre. Não gosto muito de validadores separados, pois o erro é acusado num ponto diferente de onde se originou. Considere criar seus objetos com o padrão Builder. É assim, você vai dando “set” no objeto builder e, quando estiver completo, chame o método “build” ou “newInstance” (ou o nome que você achar melhor) pra retornar seu “entity”. Não é só isso, nos métodos do builder, acrescente validações quando se perceber qualquer valor inválido. O objetivo é não deixar criar o objeto quando existem erros. A idéia é originária do livro do GoF, e foi também comentada no livro “Effective Java” de Joshua Bloch. Achei um link que fala sobre esse pattern, dê uma olhada.

Espero ter ajudado.

Lavieri

Leonardo3001:
Quando não se consegue as respostas corretas, é porque está se fazendo as perguntas erradas.

Conheço duas soluções diferentes para a validação que não involve o seu mecanismo (até porque, como você mesmo percebeu, existem “buracos”). Portanto jogue sua idéia no lixo e considere uma das duas possibilidades minhas:

  1. Não reinvente a roda. Usar Hibernate Validator, e você nem precisa do Hibernate “Core” pra usá-lo. Todas as validações são indicadas por anotações da biblioteca, e você pode ainda criar novas. E também existe uma API própria e genérica para a validação. Consulte a documentação.

  2. Falhe cedo e falhe sempre. Não gosto muito de validadores separados, pois o erro é acusado num ponto diferente de onde se originou. Considere criar seus objetos com o padrão Builder. É assim, você vai dando “set” no objeto builder e, quando estiver completo, chame o método “build” ou “newInstance” (ou o nome que você achar melhor) pra retornar seu “entity”. Não é só isso, nos métodos do builder, acrescente validações quando se perceber qualquer valor inválido. O objetivo é não deixar criar o objeto quando existem erros. A idéia é originária do livro do GoF, e foi também comentada no livro “Effective Java” de Joshua Bloch. Achei um link que fala sobre esse pattern, dê uma olhada.

Espero ter ajudado.

ja vi o validator, so que não queria me amarrar ao Hibernate… mais c vc fala que ele é idependente do Core vou dar 1 olhar melhor…

vou ver o padrão build, obrigado pela ajuda ^^

Criado 16 de dezembro de 2008
Ultima resposta 17 de dez. de 2008
Respostas 13
Participantes 8