2014-01-23 2 views
1

나는 2 개의 주어진 개체간에 다른 필드를 로깅해야하는 감사 로그와 비슷한 작업을하고 있습니다.2 개체 사이의 차이를 확인하십시오.

예를 들어, 나는 Foo 클래스의 oldFoonewFoo이라는 두 개의 객체가 있습니다. 이 클래스에는 20 개 이상의 필드가 있다고 가정 해 보겠습니다. 나는 어떤 필드가 다른지 알고 싶었습니다. 이전에 nullnewFoo의 필드는 무엇 이었습니까? oldFoo에 있지만 외롭지는 않았습니까? 값이 변경되었거나 null으로 설정된 newFoo의 필드는 무엇입니까?

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

일반적으로 전체 작업을 수행하기 위해 리플렉션을 사용할 수 있습니다.

리플렉션을 사용하여 개체의 모든 필드를 스캔하고 값이 다른 모든 필드의 목록을 작성하십시오.

그러면이 코드는 원하는 두 개체에서 작동합니다.

덧붙여서, 해시 맵을 악용하는 대신 fieldName, oldValue, newValue 필드를 사용하여 Change 클래스를 생성합니다. 수업은 훨씬 더 명확 해지고 더 가독성이 높으며 더 빠르게 실행되고 더 적은 메모리를 사용합니다.

당신은 거의 옵션이 없습니다. 주석을 사용하여 무언가를 할 수 있습니다 (멤버 변수 대신 주석을 스캔하십시오). 다른 옵션은 클래스를 HashMap으로 변경하고 멤버 변수를 전혀 갖지 않는 것입니다.

+0

아, 나는 반사를 사용하지 않으려 고합니다. – 0x56794E

+0

이런 식으로 클래스 구성 요소에 액세스하려면 실제로 리플렉션을 사용해야합니다. ** ** 이렇게하는 것은 기본 제공 방법입니다. – user2282497

+0

그럼 행운 아. 리플렉션, 어쩌면 주석 및 HashMap에 대한 클래스 도려는 거의 유일한 옵션입니다. 이것은 정확하게 반사가 만들어 졌기 때문에 내가 왜 당신이 그것을 사용하지 않을지 모르겠다. ... –

관련 문제