2012년 5월 20일 일요일

[java] object generator library는 immutable class를 만들수없다.

Effective Java에서는 별다른 이유가 없다면 class 설계시 Immutable class로 만들것을 권하고 있습니다.

원하지 않는 정보수정과 멀티 쓰레딩에 대해 고민할 거리가 없어지니, 매우 좋은 조언이라고 생각합니다.

하지만 우리가 자주 사용하는 library들 중에 원천적으로 이러한 원칙을 위배하고 있는 것들이 있습니다.
mybatis, hibernate, jaxb, jackson, gson...
등이 그렇습니다. 이러한 library들은 애초에 Immutable한 객체를 생성해낼 수 없습니다.

위 library들은 class가 아닌 무언가를 참고해서 객체를 자동으로 생성해준다는 준다는 공통점이 있습니다.
mybatis와 hibernate는 RDB를 참고해서 객체를 생성해주며, jaxb는 XML을 참고해 객체를 생성합니다. jackson과 gson은 json을 참고해 객체를 자동 생성합니다.

위 library들이 Immutable한 객체를 만들수 없는 이유는 그 생성과정 자체에 있습니다.
대부분의 경우 다음과 같은 방식으로 객체를 자동으로 생성합니다.
1. reflection을 이용해 기본 생성자로 객체를 생성
2. reflection을 이용해 setter를 호출하거나 field에 직접 주입하는 방식으로 객체에 정보를 삽입
3. 사용자에게 반환

Immutable이라하면 객체 초기화시에 모든 정보가 설정되고 그 이후로는 정보를 바꿀 수 없는 객체를 의미합니다.

하지만 위 과정을 보면 1번에서 객체를 만들고 그 이후에 2번 과정을 통해서 객체에 정보를 주입합니다. 즉, 만든 이후에 정보에 변경이 있게되는 것이고.. 이러한 과정 자체가 Immutable이라는 개념과 충돌하게 됩니다.

그럼 왜 객체를 자동으로 생성해주는..(제목에서는 object generator라고 지칭했습니다.)
library들은 중요 개념인 Immutable을 버린걸까요...

이는 library들의 설계상 오류나 한계라기 보다는 Java라는 언어의 한계라고 보여집니다.
생성시 모든 정보를 객체에 넣자면 생성자를 사용해야할텐데, reflection의 생성자 콘트롤 관련 메소드들을 보면...
생성자의 어떤 파라미터에 어떤 값을 넣어야하는지 충분한 정보들을 얻을 수 없음을 알 수 있습니다. 하고싶어도 못하는 형편인것이죠.

즉, 만약 여러분이 진행하는 Project의 모든 Statefull 객체를 Immutable로 만들고자 한다면, 이 시도는 즉시 난관에 부딫히게 될겁니다.
사용하게 될 주요 library들이 모두 Immutable이라는 개념을 포기하고 있으니까요.

만약 이러한 library를 충분히 이용하면서, Immutable이라는 목표 또한 달성하고자 한다면, 중간에 합의점을 찾아야 합니다.
모든 객체를 자동으로 생성해주는 hibernate보다는, 수동으로 객체를 생성할 수 있는 jdbc template를 사용하는 것이 나을지도 모릅니다.
json을 바로 객체로 변환하지 않고, Map으로 변환한 이후에 수동으로 그 Map의 값들을 객체에 set해주는 것이 정답일수도 있습니다.

그나마 mybatis의 경우에는 constructor의 몇번째 index에 어떤 파라미터를 넣을 것인지를 XML에 지정할 수 있어 이 문제를 피해갈수있습니다.

물론.. 이와같은 경우, 자동화된 객체 생성 방법이 아니라 수동으로 일일이 값을 Mapping 시켜주는 것에 불과하다는 근본적인 문제가 여전히 있습니다.

보통, Immutable을 포기하고 setter getter가 무분별하게 쭈욱 달린 객체를 사용함으로서 편리함을 택하고 별 문제없이 프로젝트가 진행되기 마련입니다. 하지만, object generator library를 사용할 때는 최소한 이러한 문제 의식을 갖고 사용하면 좋을겁니다.


댓글 없음:

댓글 쓰기