Ajuda com uso de Generics

2 respostas
danieldestro

Caros,

Me ajudem a pensar. Acho que travei. Quero usar generics para criar uma API mais "genérica" e extensível na minha aplicação.

É um simples programa que lê Logs e gera relatórios sobre esses logs. São diversos tipos de logs, no entanto quero usar uma API padronizada e flexível.

Basicamente pensei em ter um LogAnalyser (que vai analisar o arquivo de log e deve ser especializado por tipo de log) e um LogReport (que vai variar por tipo de log e gerar o relatório específico), além do LogStats (que guarda as estatisticas do log gerada pelo LogAnalyser e é usado pelo LogReport).

package log.analyser;
import ...;
public abstract class LogAnalyser<R> {

	public static void main(String[] args) throws LogAnalyserException {
		String tipo = "tipo_do_log";
		LogReport report = logReportFactory(tipo);
		LogAnalyser<?> analyser = analyserFactory(tipo);
		analyser.analyse(new File("arquivo_de_log"), report);
	}
	
	private static LogReport logReportFactory(String type) {
		LogReport report = cria_o_report_de_acordo_com_o_tipo;
		return report;
	}
	
	private static LogAnalyser<?> analyserFactory(String type) {
		LogAnalyser<?> analyser = cria_o_analyser_de_acordo_com_o_tipo;
		return analyser;
	}
	
	public abstract void analyse(File logfile, R report) throws LogAnalyserException;
}
package log.analyser;
import ...;
public class LoginLogAnalyser extends LogAnalyser<LoginLogReport> {
	public void analyse(File logfile, LoginLogReport report) {
		// faz análise do arquivo de log e gera um relatório
	}
}
package log.analyser.report;
public class LoginLogReport implements LogReport {
	public void generate() {
		// gera o relatório
	}
}

Meu problema aqui vai ser passar o tipo certo do LogReport para o método "analyse" do LogAnalyser.

A ideia de ter o LogReport passado no método "analyse" é poder escolher a implementação do relatório que eu quiser, já passando com os parâmetros necessário.

Sugestões?

Ou melhor fazer a boa e velha injeção??

analyser.setReport( meuLogReport );
analyser.analyse( logFile );

2 Respostas

E

Como o Generics funciona por “erasure” no caso do Java (ele não é reificado como no caso do .NET) então você é obrigado a passar também, como parâmetro, um objeto java.lang.Class representando a classe parâmetro ®.
Veja a página 17 deste documento: http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

This technique of using class literals as run time type tokens is a very useful trick
to know.

danieldestro

Tá certo. Como o negócio é simples e quero finalizar rápido, vou do jeito simples e depois tento pensar em alguma implementação mais legal num futuro refactoring. tks!

Criado 5 de outubro de 2011
Ultima resposta 5 de out. de 2011
Respostas 2
Participantes 2