원본: http://wiki.javajigi.net/pages/viewpage.action?pageId=527
애플리케이션 Registry를 이용하여 Sigleton의 확산을 피하라.
애플리케이션 Registry를 이용하여 Sigleton의 확산을 피하라.
우리들이 애플리케이션을 개발할 때 상당히 많이 사용하는 패턴중의 하나가 Singleton Design 패턴일 것이다. 그러나 Singleton 패턴은 다음과 같은 문제를 일으킨다.
- Singleton 클래스에 대한 의존관계는 다른 많은 클래스들 속에 하드코딩 되어야 한다.
- Singleton은 그 자신의 설정을 처리해야 한다. ( 잘 이해가 되지 않는 부분이다. )
- 복잡한 애플리케이션은 많은 Singleton을 갖는다. 각각은 그것의 설정 로딩을 서로 다르게 할 것이다. 이는 설정을 위한 중앙 Registry가 없음을 의미한다.
- Singleton은 인터페이스와 친밀하지 않다. 이것은 매우 좋지 않은 일이다. Singleton이 인터페이스를 구현하게 만드는 것은 권장되지 않는다. 왜냐하면, 그 후에 해당 인터페이스에 대한 다른 구현들을 막을 방법이 없기 때문이다. Singleton의 일반적인 구현은 인터페이스가 아닌 클래스에 타입을 정의하는 것이다.
- Singleton들은 상속에 잘 따르지 않는다. 왜냐하면, 특별한 클래스에 코딩을 할 필요도 없을 뿐 아니라, 자바는 Static method들의 overriding을 허용하지 않기 때문이다.
- Singleton의 상태를 Runtime시에 일관성 있게 갱신하는 것은 불가능하다. 각 Singleton이나 Factory 클래스들에 있어서의 Concurrent 갱신 시도는 무작위의 순서로 적용될 것이다. 애플리케이션 내의 모든 Singleton들의 상태를 재생할 방법은 전혀 없다.
Singleton Design 패턴의 단점을 극복하기 위하여 Rod Johnson은 다른 객체의 인스턴스를 관리하는 하나의 Registry를 가질 것을 추천하고 있다. 이 인스턴스 관리는 전담하는 객체를 Application Context라고 부른다. 이 방법의 장점은 다음과 같다.
- 인터페이스와 잘 동작한다. Singleton이 필요한 객체들이 구현 클래스에 대한 알 필요가 없다.
- 모든 객체들은 일반 자바 클래스들이고, 상속을 일반적으로 사용할 수 있다. 여기에는 어떤 static 변수도 없다.
- 설정은 클래스 외부에서, 그리고 전체적으로 프레임워크 코드에 의해서 다루어진다. Context 객체는 각 Singleton들을 인스턴스화하고 설정하는데 책임을 진다. 이것은 자바 코드 외부에서의 설정(XML문서나 RDBMS 테이블등을 이용한)이 사용될 수 있다는 것을 의미한다. 그런 설정은 객체들이 빈즈 속성을 공개하는 것만으로도 애플리케이션 Context에 의해 다루어지는 객체들 간의 객체 그래프 생성을 가능하게 하는 기능을 포함하게 된다.
- Context 객체는 인터페이스를 구현할 것이다. 이것은 코드 변경 없이도 서로 다른 구현들이 서로 다른 소스들로부터 설정을 가져올 수 있게 한다.
- Singleton들의 동적인 상태 변경이 가능하다. Context는 재생될 수 있고, 그것이 관리하는 객체들의 상태를 변경시킬 수도 있다.(물론 여기에는 Thread Safe 이슈에 대한 고려가 있어야 한다.)
- Context 객체를 사용하는 것은 다른 가능성들을 열어준다. 예를 들면, Context는 독립적인 객체 인스턴스들을 위한 Factory로서 동작하는 Prototype Design 패턴의 구현같은 다른 서비스들을 제공할 수도 있다. 많은 애플리케이션 객체들이 그것에 접근할 수 있기 때문에, Context 객체는 Observer 설계 패턴의 이벤트 제공자로서 동작할 수도 있다.
- Singleton Design 패턴은 유연하지는 않지만, 만일 이것이 유용하다면 여러분은 여러 애플리케이션 Context 객체를 가지기 위해 선택할 수 있다.