Melhor opção ao instanceof

7 respostas
I

Boa noite, sei que o meu post parece repetitivo pelo nome do instanceof mas é que gostaria da ajuda de você para resolver uma implementação que acho muito feia mas não achar uma forma melhor de fazer.
O problema: estou utilizando uma API de terceiros para fazer um parser, essa API em determinado momento me retorna um List de classes que implementam uma interface genérica, preciso percorrer esse list e fazer o devido tratamento para cada classe, então criei um método que recebe cada objeto e faço o tratamento com o instancef verificando o tipo do objeto e fazendo o tratamento.
Muitas vezes vi neste fórum e em outros falando para evitar o uso de instanceof e também um numero exagerado de if´s. Gostaria de saber, qual a melhor forma de fazer esse tratamento então sem utilizar essa estrutura.

Ex.:

public interface Expression {

}
public class Parse {
	
	public void parse(Expression expression){
		
		if(expression instanceof Table){
			this.parseTable((Table)expression);
		}else if(expression instanceof Function){
			this.parseFunction((Function)expression);
		}else if(expression instanceof Procedure){
			this.parseProcedure((Procedure)expression);
		}else{
			//DEMAIS IMPLEMENTACOES
		}
		
	}

}

7 Respostas

S

Eu faria assim:

public void parse(Table table) {
this.parseTable(table);
}

public void parse(Function function) {
this.parseFunction(function);
}

public void parse(Procedure procedure) {
this.parseProcedure(procedure);
}

E ainda mataria todos os if’s.

Filipe_A

Sem_Nome:
Eu faria assim:

public void parse(Table table) {
this.parseTable(table);
}

public void parse(Function function) {
this.parseFunction(function);
}

public void parse(Procedure procedure) {
this.parseProcedure(procedure);
}

E ainda mataria todos os if’s.

Olá! Mas ainda assim ele não precisaria de “ifs” para saber qual função chamar?

Acho que o jeito que foi feito não está ruim, tendo um local só pra alterar quando necessário…

Abraços.

Ruttmann

Filipe A.:
Sem_Nome:
Eu faria assim:

public void parse(Table table) {
this.parseTable(table);
}

public void parse(Function function) {
this.parseFunction(function);
}

public void parse(Procedure procedure) {
this.parseProcedure(procedure);
}

E ainda mataria todos os if’s.

Olá! Mas ainda assim ele não precisaria de “ifs” para saber qual função chamar?

Acho que o jeito que foi feito não está ruim, tendo um local só pra alterar quando necessário…

Abraços.

De jeito nenhum!

Você não conhece o conceito de sobrecarga de métodos?

Todos estes tipos que ele avalia com os IF’s implementam a interface citada.

Fazendo um método pra cada tipo ele se livra dos IF’s e do instanceof, utilizando a sobrecarga. A própria JVM vai saber qual método chamar baseando-se no tipo passado como argumento…

Filipe_A

Ruttmann:
Filipe A.:
Sem_Nome:
Eu faria assim:

public void parse(Table table) {
this.parseTable(table);
}

public void parse(Function function) {
this.parseFunction(function);
}

public void parse(Procedure procedure) {
this.parseProcedure(procedure);
}

E ainda mataria todos os if’s.

Olá! Mas ainda assim ele não precisaria de “ifs” para saber qual função chamar?

Acho que o jeito que foi feito não está ruim, tendo um local só pra alterar quando necessário…

Abraços.

De jeito nenhum!

Você não conhece o conceito de sobrecarga de métodos?

Todos estes tipos que ele avalia com os IF’s implementam a interface citada.

Fazendo um método pra cada tipo ele se livra dos IF’s e do instanceof, utilizando a sobrecarga. A própria JVM vai saber qual método chamar baseando-se no tipo passado como argumento…

Conheço o conceito sim… entendi agora, valeu!

A

Ruttmann:

Você não conhece o conceito de sobrecarga de métodos?

Todos estes tipos que ele avalia com os IF’s implementam a interface citada.

Fazendo um método pra cada tipo ele se livra dos IF’s e do instanceof, utilizando a sobrecarga. A própria JVM vai saber qual método chamar baseando-se no tipo passado como argumento…

Na verdade, a sobrecarga de método não funciona exatamente assim.

Ela irá utilizar o tipo declarado do objeto e não a classe da instancia como base.

O ideal seria o método parse pertencer a interface Expression, daí você poderia usar polimorfismo.

G

AbelBueno:
Ruttmann:

Você não conhece o conceito de sobrecarga de métodos?

Todos estes tipos que ele avalia com os IF’s implementam a interface citada.

Fazendo um método pra cada tipo ele se livra dos IF’s e do instanceof, utilizando a sobrecarga. A própria JVM vai saber qual método chamar baseando-se no tipo passado como argumento…

Na verdade, a sobrecarga de método não funciona exatamente assim.

Ela irá utilizar o tipo declarado do objeto e não a classe da instancia como base.

O ideal seria o método parse pertencer a interface Expression, daí você poderia usar polimorfismo.

Mas AbelBueno,
Com isso não limitaria o cara a apenas uma assinatura do método? Ou usaria a sobrecarga dentro da interface?

I

Obrigado pelas respostas e desculpe a demora em me pronunciar.

Conheço orientação a objeto e pensei em fazer do modo que falou:

Filipe A.:
Ruttmann:
Filipe A.:
Sem_Nome:
Eu faria assim:

public void parse(Table table) {
this.parseTable(table);
}

public void parse(Function function) {
this.parseFunction(function);
}

public void parse(Procedure procedure) {
this.parseProcedure(procedure);
}

E ainda mataria todos os if’s.

Olá! Mas ainda assim ele não precisaria de “ifs” para saber qual função chamar?

Acho que o jeito que foi feito não está ruim, tendo um local só pra alterar quando necessário…

Abraços.

De jeito nenhum!

Você não conhece o conceito de sobrecarga de métodos?

Todos estes tipos que ele avalia com os IF’s implementam a interface citada.

Fazendo um método pra cada tipo ele se livra dos IF’s e do instanceof, utilizando a sobrecarga. A própria JVM vai saber qual método chamar baseando-se no tipo passado como argumento…

Conheço o conceito sim… entendi agora, valeu!

mas como o list me retorna um Expression preciso de alguma forma fazer o cast de Expression para Table, Function e demais, pois o java não faz isso implícito, correto ?

Lendo melhor a documentação da API vi uma solução para melhorar a implementação, é implementado nele um padrão de projeto chamado Visitor, que resolve esse problema. Estou tentando utilizar esse padrão.

Criado 29 de agosto de 2013
Ultima resposta 30 de ago. de 2013
Respostas 7
Participantes 6