2014-01-23 5 views
1

Я работаю над чем-то похожим на журнал аудита, который требует регистрации полей, которые отличаются между двумя заданными объектами.Определите различия между двумя объектами

Например, у меня есть эти 2 объекта, oldFoo и newFoo класса Foo. Допустим, у этого класса более 20 полей. Я хотел бы знать, какие поля отличаются друг от друга - каковы поля в newFoo, которые были ранее null в oldFoo, но нет равных? Каковы поля в newFoo, значения которых были изменены или установлены на null.

Конечно, я всегда могу сделать это немой способ, как это:

Map<String, List<Map<String, Object>> diff (Foo oldFoo, Foo newFoo) 
{ 
    Map<String, List<Map<String, Object>> ret = new HashMap<String, List<Map<String, Object>>(); 
    List<Map<String, Object>> added = new ArrayList<Map<String, Object>>(); 
    List<Map<String, Object>> changed = new ArrayList<Map<String, Object>>(); 
    List<Map<String, Object>> removed = new ArrayList<Map<String, Object>>(); 

    if (newFoo.getField1() != null && oldFoo.getField1() == null) 
    { 
    added.add(new HashMap<String, Object>().put("fieldName", "field1") 
              .put("oldValue", "") 
              .put("newValue", newFoo.getField1()); 
    } 
    else if (newFoo.getField1() == null && oldFoo.getField1() != null) 
    { 
    removed.add(new HashMap<String, Object>().put("fieldName", "field1") 
               .put("oldValue", oldFoo.getField1()) 
               .put("newValue", ""); 
    } 
    else if (newFoo.getField1() != null && oldFoo.getField1() != null && !newFoo.getField1().equals(oldFoo.getField1()) 
    { 
    changed.add(new HashMap<String, Object>().put("fieldName", "field1") 
               .put("oldValue", oldFoo.getField1()) 
               .put("newValue", newFoo.getField1()); 

    } 

    //keep going for *MORE THAN 20* fields... :(
    //... 

    ret.put("CHANGED", changed); 
    ret.put("ADDED", added); 
    ret.put("REMOVED", removed); 
    return ret; 

} 

Но я уверен, что там должен быть умным, как там. Любое предложение?

* Обновление 1 * Я стараюсь избегать использования отражения настолько, насколько возможно.

ответ

0

Вы можете использовать отражение, чтобы сделать все это в целом.

Просто сканируйте каждое поле объекта с помощью отражения и создайте список из каждого поля, имеющего другое значение.

Этот код будет работать с любыми двумя объектами, которые вам нравятся!

Кстати, я бы создать Change класс с fieldName, oldValue, newValue полей, а не злоупотребляющих хэш-карты для этого. Класс будет намного четче/читабельнее, быстрее работать, использовать меньше памяти и т. Д.

Без отражения у вас очень мало вариантов. Возможно, вы сможете сделать что-то с аннотациями (сканирование аннотаций, а не переменных-членов). Другой вариант - изменить класс на HashMap и не иметь переменных-членов вообще.

+0

А, я должен был упомянуть, что я пытаюсь НЕ использовать отражение. – 0x56794E

+0

Вы действительно должны использовать отражение для доступа к компонентам классов таким образом. Это ** ** встроенный способ сделать это. – user2282497

+0

Тогда вам в значительной степени не повезло. Отражение, может быть, аннотации и отключение вашего класса для HashMap - это в значительной степени ваши варианты. Это как раз то, что было построено для отражения, хотя я не знаю, почему вы его не использовали ... –

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