Search code examples
javagenericsgeneric-programmingtype-erasure

Generic interface vs interface for each type


There are two classes X, Y which implement a Base interface There is an interface which takes care of processing the objects of each type

interface Base {
}
class X implements Base {
}
class Y implements Base {
}

interface XProcessor {
    void process(X object);
}
interface YProcessor {
    void process(Y object);
}

But the downside of such approach is that i have to expose one interface for each type of object(X,y..) and if there are many such objects i would end up exposing too many interfaces. I thought i would handle this by exposing just one interface which takes care of processing objects of type Base

interface Processor<E extends Base> {
  void process(E object);
}

The implementer writes his own implementation for processing objects of type X as

class XProcessor implements Processor<X> {
    void process(X object) {
        //do something
    }
}

The problem with such approach is when i have to call the method process, at runtime, i do not know which type of object i should pass to the processor, since at runtime i cannot determine the type of that processor

void process(Processor p) {
    p.process(??);
}

Is there are a better way to handle this problem?


Solution

  • as @tredontho has suggested can use a factory 'ProcessorFactory' like below to get the relevant instance and then call the process method

    public class ProcessTest {
    
        <T extends Base> void processBase(T base) {
            ProcessorFactory.getProcessor(base).process(base);
        }
    
    }
    
    
    interface Base{
    }
    class X implements Base{
    }
    class Y implements Base{
    }
    
    interface Processor<E extends Base>{
        void process(E object);
    }
    
    interface XProcessor extends Processor<X> {
    
    }
    interface YProcessor extends Processor<Y> {
    
    }
    
    class ProcessorFactory {
    
        @SuppressWarnings("unchecked")
        static <T extends Base> Processor<T> getProcessor(T base) {
            if (base instanceof X) {
                return (Processor<T>) new XProcessorImpl();
            }
            return null;
        }
    
    }
    
    class XProcessorImpl implements XProcessor {
    
        @Override
        public void process(X object) {
            // TODO Auto-generated method stub
    
        }
    
    }