1

Предположим, что у меня есть этот класс POJO, который реализует интерфейс, но здесь нет общих атрибутов.Инициализировать POJO динамически с помощью другого метода

public interface MainIfc {} 

class Ifc1 implements MainIfc { 
    private String a1; 
    public String getA1() { 
     return a1; 
    } 
    public void setA1(String a1) { 
     this.a1 = a1; 
    } 
} 

class Ifc2 implements MainIfc { 
    private String x1; 
    private String x2; 
    public String getX1() { 
     return x1; 
    } 
    public void setX1(String x1) { 
     this.x1 = x1; 
    } 
    public String getX2() { 
     return x2; 
    } 
    public void setX2(String x2) { 
     this.x2 = x2; 
    } 
} 

И вместе с этими классами POJO у меня есть несколько методов, которые я могу использовать, чтобы получить тип POJO возвращается на основе другого значения и фактической POJO со значениями.

public class GetIfc { 
    public Class getIfcType(int code) { 
     if (code==1) 
      return Ifc1.class; 
     else 
      return Ifc2.class; 
    } 
    public MainIfc getIfc(int code) { 
     if (code==1) { 
      Ifc1 thisIfc = new Ifc1(); 
      thisIfc.setA1("Ifc1"); 
      return thisIfc; 
     } else { 
      Ifc2 thisIfc = new Ifc2(); 
      thisIfc.setX1("Ifc2"); 
      thisIfc.setX2("Ifc2"); 
      return thisIfc; 
     } 
    } 
} 

Есть ли способ, с помощью которого я могу прочитать конкретную POJO безопасно в моем коде и использовать геттеры/сеттеры? Я рассмотрел довольно много вопросов, которые дают ответы на основе Reflection, но это не работает для меня. Геттеры/сеттеры не видны и когда я звоню. getClass() на возвращенном объекте Я вижу, что это интерфейс MainIfc.

Проблема проектирования, которую я пытаюсь решить, относится к инфраструктуре автоматизации REST API, которую я пытаюсь создать. В основном у меня есть парсер ClientResponse, который отправит обратно POJO, который я ищу. Но я не хочу, чтобы люди, записывающие тестовые примеры, беспокоились о возвращаемом типе POJO. Поэтому я думал, что смогу вернуть тип и созданный POJO, чтобы получить значения, но я обеспокоен тем, как добиться этого динамически.

+0

Непонятно, что вы пытаетесь сделать. Я чувствую стремление к подобному Бин-поведению, но могу ошибаться. – Fildor

+1

", когда я вызываю .getClass() в возвращаемом объекте, я вижу, что это интерфейс MainIfc." Я считаю, что трудно поверить. Добавьте немного кода, который показывает это поведение. Также, пожалуйста, уточните: вы ищете какой-либо способ заставить его работать, или вас интересует правильный способ OO для решения этой проблемы? – Cephalopod

+0

Вы можете добавить в свои классы метод, который возвращает все (общедоступные) поля в виде списка объектов «Поле». Вероятно, член MainIfc. Тем не менее, я чувствую, что это X-Y-Question. В чем проблема, которую вы пытаетесь решить? – Fildor

ответ

0

Действительно ли потребителям MainIfc нужны POJO или только данные внутри них?

Это может быть более чистый дизайн, если MainIfc объявляет метод или два, которые предоставляют данные, которые нужны его потребителям. Затем ваши POJO могут реализовать методы, которые объявляет интерфейс MainIfc. Или вы можете создать класс-оболочку для каждого POJO, который соответствует его интерфейсу, если вы хотите, чтобы проблемы с реализацией вашего интерфейса были отделены от ваших POJO.

В идеале интерфейс должен выставлять несколько методов, которые могут использоваться для взаимодействия с любым классом, который его реализует, и никто не должен знать о базовых POJO/реализации.

public interface MainIfc { 
    public Hash getAttributes(); 
    public setAttributes(Hash attributes); 
} 

class Ifc1 implements MainIfc { 
    private String a1; 
    public String getA1() { 
    return a1; 
    } 
    public void setA1(String a1) { 
    this.a1 = a1; 
    } 
    public Hash getAttributes() { 
    // return a hash with data that MainIfc consumer will need from this POJO 
    } 
    public setAttributes(Hash attributes) { 
    // copy hash attributes to corresponding POJO fields 
    } 
} 

class Ifc2 implements MainIfc { 
    private String x1; 
    private String x2; 
    public String getX1() { 
    return x1; 
    } 
    public void setX1(String x1) { 
    this.x1 = x1; 
    } 
    public String getX2() { 
    return x2; 
    } 
    public void setX2(String x2) { 
    this.x2 = x2; 
    } 
    public Hash getAttributes() { 
    // return a hash with data that MainIfc consumer will need from this POJO 
    } 
    public setAttributes(Hash attributes) { 
    // copy hash attributes to corresponding POJO fields 
    } 
} 
1

Попробуйте этот код. Возможно, это вернет все методы в классе, а также методы, унаследованные от класса Object.

public static void main(String[] args) throws ClassNotFoundException { 
     GetIfc getIfc=new GetIfc(); 
     MainIfc clas1s=getIfc.getIfc(1); 
     Class class1= clas1s.getClass(); 
     System.out.println(class1); 
     Method[] mem= class1.getMethods(); 
     for(Method mmm : mem) { 
      System.out.println(mmm.getName()); 
     } 
    } 
+0

Я обновил свой вопрос по поводу точного требования и проблемы с дизайном, с которыми я столкнулся. Пожалуйста, порекомендуйте. – mbsingh

0

Это звучит так, как будто вы пытаетесь сделать что-то довольно нелогичное. Шаблон стратегии или абстрактная фабрика могут хорошо подходить для вашего требования, но на данный момент я не совсем понимаю, что именно вы пытаетесь достичь. Вы определенно не должны быть условно отбрасывать и называть разные методы для этих классов. Если вы действительно хотите продолжить этот путь, я бы предложил пойти с размышлением, если бы не вариант, и вам нужна гибкость, я бы, вероятно, пошел с какой-то Картой.

Но я определенно переосмыслил бы ваш дизайн, если это вообще возможно.

0

Попробуйте этот кусок кода, я не знаю, полностью ли я понимаю ваши требования, но основываясь на моем понимании, я думаю, что ниже код будет делать трюк.

public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, 
    IllegalArgumentException, InvocationTargetException { 
GetIfc getIfc = new GetIfc(); 
MainIfc clas1s = getIfc.getIfc(1); 
Field[] fields = clas1s.getClass().getDeclaredFields(); 
for (int i = 0; i < fields.length; i++) { 
    Field field = fields[i]; 
    Class fieldClasslasse = field.getType(); 

    if (field.getModifiers() == Modifier.PRIVATE) { 

    // you need to check fieldClass, if it is boolean then initials of the getter could be 'is' instead of 'get' 
    String methodNameGet = "get" + Character.toUpperCase(field.getName().charAt(0)) 
     + field.getName().substring(1); 
    String methodNameSet = "set" + Character.toUpperCase(field.getName().charAt(0)) 
     + field.getName().substring(1); 

    Method methodGet = clas1s.getClass().getDeclaredMethod(methodNameGet, null); 
    Object value = methodGet.invoke(clas1s, null); 
    if (value != null && value instanceof String) { 
     String valueUpper = ((String)value).toUpperCase(); 

     Class[] cArg = new Class[1]; 
     cArg[0] = String.class; 
     Method methodSet = clas1s.getClass().getDeclaredMethod(methodNameSet, cArg); 
     Object[] var = new Object[1]; 
     var[0] = valueUpper; 
     methodSet.invoke((Object) clas1s, var); 
    } 

    } 
} 

} 

Небольшое пояснение о коде выше: Получить все fileds объекта и проверить, является частной собственностью, если да, то он должен иметь публичный геттер и сеттер, угадать их названия на основе Java конвенции, звоните getter, получите значение, проверьте, является ли это экземпляром класса String, если да, сделайте его UPPERCASE, затем вызовите setter, чтобы установить новое значение.

Смежные вопросы