Search code examples
javaoopfactoryfactory-pattern

Java factory pattern - load classes dynamically


I have a lot of classes UNO,HAV,MAS,KOS I want to create a factory pattern.

 validator.load("UNO").validate();

I need dynamically load classes into validator class and return an instance.
(dynamically set name of the class and return an instance)
My problem is: how can I return the instance of a class, if I have incompatible types?

I don't know what to write in return type of method.

The main problem in the Validator CLASS.

public SegmentAbstract load(String str) {

AND

return SegmentAbsClass.forName(identify);

Main class

try{
   validator.load("UNO").validate();
}catch(Exception e){
   System.out.print("No class ");
}

Abstract Class (SegmentAbstract)

public abstract class SegmentAbstract {

  public abstract Boolean validate();
}

Class UNO

public class UNA extends SegmentAbstract{

  public Boolean validate() {
    System.out.print("UNO!!");
    return true;
  }

}

Class Validator

public class Validator {

  public SegmentAbstract load(String str) {
    String identify = str.substring(0, 3);
    try {

      return SegmentAbsClass.forName(identify);
    }
    catch(Exception e) {
      return this;
    }

  }
}

Solution

  • I will do something like that:

    // ISegment.java
    public interface ISegment {
        Boolean validate();
    }
    
    // Uno.java
    public class Uno implements ISegment {
        public Boolean validate() {
            System.out.print("UNO!!");
            return true;
        }
    }
    
    // SegmentFactory.java
    public final class SegmentFactory {
        public static enum Supported {
            UNO("uno", Uno.class), /* ... */, HAV("hav", Hav.class);
    
            private final Class<?> clazz;
            private final String name;
    
            private Supported(final String name, final Class<?> clazz) {
                this.name = name;
                this.clazz = clazz;
            }
    
            public Class<?> getClazz() {
                return clazz;
            }
    
            public static Supported for(final String name) {
                for (final Supported s : values()) {
                    if (s.name.equals(name) {
                        return s;
                    }
                }
                return null; // a default one
            }
        }
    
        public static ISegment create(final Supported supp) {
            if (supp == null) {
                return null;
            }
            return supp.getClazz.newInstance();
        }
    
        private SegmentFactory() {
            // avoid instantiation
        }
    }
    

    usage:

    final ISegment sa = SegmentFactory.create(SegmentFactory.Supported.for("uno"));
    sa.validate();
    

    Not tested!!