2

I have a java code like this-

Sample obj;
if(obj instanceOf Class1) 
{
    method1(obj);
} else if(obj instanceOf Class2) 
{
    method2(obj);
} else if(obj instanceOf Class3) 
{
    method3(obj);
}

Class1, Class2 and Class3 are actually DTO's and they are children of Sample, so I don't want to write business logic in DTO's.

I want to write the logic of method1, mehtod2 and method3 in a different class. Is there a design pattern for that. I am using spring MVC.

Basically, I am looking for some non-java technique to call the appropriate based on the instance instead of checking with instanceOf every single time.

Farrukh Chishti
  • 7,652
  • 10
  • 36
  • 60

3 Answers3

2

Define a method interface and implement the common interface in Class1, Class2 and Class3 - delegate to method1, method2 or method3 as appropriate in the implementation in those classes. Program to the common interface.

obj.method();
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Class1, Class2 and Class3 are actually DTO's and they are children of Sample, so I don't want to write business login in DTO's. I'll update the question as well. – Farrukh Chishti Apr 29 '18 at 22:26
2

Not a good one but let's try

  • Create an Interface

    public interface Processor {

    void process(Simple simple);
    

    }

  • Write implementation for each subclass of Sample // Class1 Processor public class Class1Processor implements Processor {

    @Override
    public void process(Simple simple) {
        System.out.println("Class1 processing completed");
    }
    

    } // Class2 Processor public class Class2Processor implements Processor {

    @Override
    public void process(Simple simple) {
        System.out.println("Class2 processing completed");
    }
    

    }

  • Processor Factory Class public class ProcessorFactory {

    private static final Map<Class<? extends Simple>, Processor> LOOKUP = new HashMap<>();
    
    static {
        LOOKUP.put(Class1.class, new Class1Processor());
        LOOKUP.put(Class2.class, new Class2Processor());
    }
    
    public static <T extends Simple> Processor getProcessor(T obj) {
        return LOOKUP.get(obj.getClass());
    }
    

    }

  • And Lastly Main Class public static void main(String[] args) {

    Simple class1 = new Class1();
    Simple class2 = new Class2();
    
    ProcessorFactory.getProcessor(class1).process(class1);
    ProcessorFactory.getProcessor(class2).process(class2);
    

    }

Hemant Patel
  • 3,160
  • 1
  • 20
  • 29
1

How about create a custom annotation for classes? Does this solve your problem about business logic etc. Something like

@CustomMethodName(method="method1")
public class Class1{
 //..
}
@CustomMethodName(method="method2")
public class Class2{
 //..
}
@CustomMethodName(method="method3")
public class Class3{
 //..
}

After you should get your method name by using

Class<?> aClass = Sample.class;
Annotation[] annotations = aClass.getAnnotations();
for(Annotation annotation : annotations){
    if(annotation instanceof CustomMethodName){
        CustomMethodName myAnnotation = (CustomMethodName) annotation;
        String methodName = myAnnotation.method();
        java.lang.reflect.Method method;
        try {
           method = obj.getClass().getMethod(methodName);// get method wherever you define them
           method.invoke(obj);//execute method
        } catch (SecurityException e) { ... }
          catch (NoSuchMethodException e) { ... }
     }
}
Abdullah Tellioglu
  • 1,434
  • 1
  • 10
  • 26