2015-08-26 2 views
3

Скажем, у меня есть следующий POJO:Знаете ли вы какие-либо библиотеки, которые берут объект, и возвращают строку, представляющую, как этот объект может быть построен с использованием его класса-строителя?

public class Student { 

    private String firstName; 
    private String lastName; 

    public Student(){}; 

    public Student(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 
} 

и его строитель:

public class StudentBuilder { 

    private Student student; 

    public StudentBuilder() { 
     this.student = new Student(); 
    } 

    public StudentBuilder withFirstName(String firstName) { 
     this.student.setFirstName(firstName); 
     return this; 
    } 

    public StudentBuilder withLastName(String lastName) { 
     this.student.setLastName(lastName); 
     return this; 
    } 

    public Student build() { 
     return this.student; 
    } 
} 

Учитывая, что у меня есть экземпляр класса Student, есть библиотека, которая может взять объект студент, как параметр и возвращает строку, представляющую предложение, чтобы создать экземпляр этого конкретного объекта с помощью его построителя?

Использование должно быть что-то вроде:

public static void main(String[] args) { 
     Student student = new Student("John", "Smith");  
     String builderInstantiator = StringObjectInstantiator.generate(student); 
     Assert.assertEquals("new StudentBuilder().withFirstName(\"John\").withLastName(\"Smith\").build();", builderInstantiator); 
} 

Я имею в виду, чтобы спросить вокруг немного перед началом ее реализации с нуля.

Краткая история: Один из модулей приложения, над которым я работаю, предоставит мне json-файл, содержащий сериализованные pojos. Основываясь на этом json, я должен сгенерировать несколько классов java, которые создают экземпляры этих объектов, используя их создателей.

ввода пробы: проба

[ 
    { 
     "firstName": "John", 
     "lastName": "Smith" 
    }, 
    { 
     "firstName": "David", 
     "lastName": "Winter" 
    }, 
    { 
     "firstName": "Rebecca", 
     "lastName": "Cross" 
    } 
] 

Выход:

public class StudentProvider { 

    public List<Student> get() { 
     return Arrays.asList(
       new StudentBuilder().withFirstName("John").withLastName("Smith").build(), 
       new StudentBuilder().withFirstName("David").withLastName("Winter").build(), 
       new StudentBuilder().withFirstName("Rebecca").withLastName("Cross").build() 
       ); 
    } 
} 
+0

Возможно, вы нашли что-то в коде, который реализует шаблоны IDE. –

+0

https://github.com/mkarneim/pojobuilder –

+0

Теперь вы очень заинтересовались тем, почему вы спрашиваете об этом :) – Thirler

ответ

2

Я полагаю, вы могли бы искать какой-то генерации кода, но я не думаю, что там будет библиотека, которая делает именно то, что ты хочешь. Вы можете попробовать некоторые генераторы-генераторы, такие как pojo builder и отредактировать источники (или для плагинов eclipse, таких как Fluent builders).

В дополнение к этому генерация строки будет легкой, если объект содержит только простые типы, такие как String, char, int и т. Д. Какой код он должен сгенерировать, если в нем есть пользовательский объект. Скажем, например, если класс Student имеет поле типа Object, каким должно быть значение, которое необходимо передать методуXXX()? Если бы вы могли гарантировать, что объект под вопросом будет содержать только простые поля, было бы лучше написать свой собственный метод. Просто что-то вроде

public static String generate(Object obj){ 
    StringBuilder str = new StringBuilder("new " + obj.getClass().getSimpleName() + "()"); 
    Field[] allFields = obj.getClass().getDeclaredFields(); 
     for (Field field : allFields) { 
      field.setAccessible(true); 
      try { 
      str.append(".with").append(capitalize(field.getName())).append("(").append(resolveField(field.get(obj))).append(")"); 
     } catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
     } 
    return str.append(".build();").toString(); 
} 

NB: Это быстрое решение, возможно, не идеальное. Полный пример

import java.lang.reflect.Field; 

class CustomObject { 
    String innerValue1; 
    String innerValue2; 

    public CustomObject(String innerValue1, String innerValue2) { 
     this.innerValue1 = innerValue1; 
     this.innerValue2 = innerValue2; 
    } 
    public String getInnerValue1() { 
     return innerValue1; 
    } 
    public void setInnerValue1(String innerValue1) { 
     this.innerValue1 = innerValue1; 
    } 
    public String getInnerValue2() { 
     return innerValue2; 
    } 
    public void setInnerValue2(String innerValue2) { 
     this.innerValue2 = innerValue2; 
    } 
} 

class Student { 

    private String firstName; 
    private String lastName; 
    private int sample; 
    private char sampleChar; 
    private CustomObject obj; 

    public Student(){}; 

    public Student(String firstName, String lastName, int sample, char sampleChar, CustomObject obj) { 
    this.firstName = firstName; 
    this.lastName = lastName; 
    this.sample = sample; 
    this.sampleChar = sampleChar; 
    this.obj = obj; 
    } 

    public String getFirstName() { 
    return firstName; 
    } 

    public void setFirstName(String firstName) { 
    this.firstName = firstName; 
    } 

    public String getLastName() { 
    return lastName; 
    } 

    public void setLastName(String lastName) { 
    this.lastName = lastName; 
    } 

    public int getSample() { 
     return sample; 
    } 

    public void setSample(int sample) { 
     this.sample = sample; 
    } 

    public CustomObject getObj() { 
     return obj; 
    } 

    public void setObj(CustomObject obj) { 
     this.obj = obj; 
    } 

    public char getSampleChar() { 
     return sampleChar; 
    } 

    public void setSampleChar(char sampleChar) { 
     this.sampleChar = sampleChar; 
    } 
} 

public class StringObjectInstantiator { 

    public static String generate(Object obj, boolean appenColon){ 
     StringBuilder str = new StringBuilder("new " + obj.getClass().getSimpleName() + "()"); 
     Field[] allFields = obj.getClass().getDeclaredFields(); 
     for (Field field : allFields) { 
     field.setAccessible(true); 
     try { 
       str.append(".with").append(capitalize(field.getName())).append("(").append(resolveField(field.get(obj))).append(")"); 
      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } 
     } 
     str.append(".build()"); 
     return appenColon ? str.append(";").toString() : str.toString(); 
    } 

    private static String resolveField(Object fieldValue) { 
     String className = fieldValue.getClass().getSimpleName(); 
     if("String".equals(className)){ 
      return "\"" + fieldValue + "\""; 
     } else if("Character".equals(className)){ 
      return "'" + fieldValue + "'"; 
     } else if("Number".equals(fieldValue.getClass().getSuperclass().getSimpleName())){ 
      return fieldValue.toString(); 
     } else { 
      return generate(fieldValue, false); 
     } 
    } 

    private static String capitalize(final String line) { 
     return Character.toUpperCase(line.charAt(0)) + line.substring(1); 
    } 

    public static void main(String[] args) { 
     System.out.println(generate(new Student("James", "Bond", 2, 'J', new CustomObject("A", "B")), true)); 
    } 

} 
+0

Спасибо за образец! Поскольку я не думаю, что кто-то написал библиотеку для моего варианта использования, я буду следовать этому подходу с использованием рефлексии + рекурсии. Я на самом деле написал большую часть этого, просто я хотел проверить, есть ли более элегантный способ сделать это. :-). POJO, над которыми я работаю, не содержат только примитивных членов. Я хочу! :-) Они также содержат списки, карты, другие объекты и т. Д., Поэтому я потрачу некоторое время на их обработку. Во всяком случае, спасибо за образец! – AndreiB

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

  • Нет связанных вопросов^_^