I want to share my answer for this question on StackOverflow.
Say you want to process several objects with different types. Each type must be processed differently but some concerns are:
- You don’t want if-then-else solution which is obviously not great for long-term
- Configuration is also bad for the same reason
So how is the solution? This is the solution that is using library from Reflections.
public class A {
}
public class B {
}
import java.lang.reflect.ParameterizedType;
public abstract class Processor<T> {
private final Class<T> processedClass;
public Processor() {
ParameterizedType parameterizedType =
(ParameterizedType) getClass().getGenericSuperclass();
processedClass =
(Class<T>) parameterizedType.getActualTypeArguments()[0];
}
public Class<T> getProcessedClass() {
return processedClass;
}
protected abstract void process(T message);
}
public class ProcessorA extends Processor<A> {
@Override
protected void process(A message) {
System.out.println("Processing object A");
}
}
public class ProcessorB extends Processor<B> {
@Override
protected void process(B message) {
System.out.println("Processing object B");
}
}
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.reflections.Reflections;
public class Adapter {
private Map<Class<?>, Processor<Class<?>>> mapping
= new HashMap<Class<?>, Processor<Class<?>>>();
public Adapter() throws Exception {
Reflections r = new Reflections("");
Set<Class<? extends Processor>> subTypesOf =
r.getSubTypesOf(Processor.class);
for (Iterator iterator = subTypesOf.iterator();
iterator.hasNext();) {
Class<? extends Processor> c =
(Class<? extends Processor>) iterator.next();
Constructor<? extends Processor> constructor =
c.getConstructor();
Processor p = constructor.newInstance();
mapping.put(p.getProcessedClass(), p);
}
}
public <T> Processor<T> getProcessor(
Class<? extends T> c) {
return (Processor<T>) mapping.get(c);
}
}
public class Main {
public static void main(String[] args)
throws Exception {
Adapter adapter = new Adapter();
A a = new A();
adapter.getProcessor(a.getClass()).process(a);
B b = new B();
adapter.getProcessor(b.getClass()).process(b);
}
}
The console after running main method:
14:01:37.640 [main] INFO org.reflections.Reflections - Reflections took 375 ms to scan 4 urls, producing 222 keys and 919 values Processing object A Processing object B
It’s kind of magic, isn’t it?
Related posts:
0 Responses to “Java Tips: Process Object Based On Its Type Without if-then-else Solution”