Шаблон фабрики Java - загрузка классов динамически - PullRequest
2 голосов
/ 10 декабря 2011

У меня много классов UNO, HAV, MAS, KOS Я хочу создать фабричный шаблон.

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

Мне нужно динамически загружать классы в класс валидатора и возвращать экземпляр.
(динамически установить имя класса и вернуть экземпляр)
Моя проблема: как я могу вернуть экземпляр класса, если у меня есть несовместимые типы?

Я не знаю, что написать в возвращаемом типе метода.

Основная проблема в Validator CLASS .

public SegmentAbstract load(String str) {

И

return SegmentAbsClass.forName(identify);

Основной класс

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

Абстрактный класс (SegmentAbstract)

public abstract class SegmentAbstract {

  public abstract Boolean validate();
}

Класс UNO

public class UNA extends SegmentAbstract{

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

}

Класс валидатора

public class Validator {

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

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

  }
}

Ответы [ 3 ]

2 голосов
/ 10 декабря 2011

Попробуйте это:

public interface Validator {
    boolean validate(Object obj);
}

public final class ValidatorFactory {
    private ValidatorFactory(){}

    public static Validator load(String type){
        try {
            Class<?> clazz = Class.forName(type);
            if (Arrays.asList(clazz.getInterfaces()).contains(Validator.class)){
                return (Validator) clazz.newInstance();
            }
            throw new IllegalArgumentException("Provided class doesn't implement Validator interface");
        } catch (Exception e) {
            throw new IllegalArgumentException("Wrong class provided", e);
        } 
    }
}

Может быть, это поможет ???

1 голос
/ 10 декабря 2011

Я сделаю что-то подобное:

// 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
    }
}

использование:

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

Не проверено !!

1 голос
/ 10 декабря 2011

Взгляните здесь .Вкратце, идея состоит в том, чтобы создать карту в вашем фабричном классе (Map<String,String>, ключ - это идентификатор, значение - полное имя класса) и добавить поддерживаемые классы во время инициализации.Затем вы используете отражение, чтобы создать экземпляр объекта в вашем фабричном методе.Кроме того, вы можете избежать отражения, используя Map<String, SegmentAbstract> вместо Map<String,String> и добавляя public abstract getNewSegment() к вашему SegmentAbstract классу.

...