클래스가 내부에 특정 자원에 의존하고, 그 클래스의 행동이 특정 자원에 따라 영향을 많이 받으면, 싱글톤과 정적 유틸리티 클래스로 구현하면 안된다. 이런 영향력이 있는 자원을 클래스 내부에서 만들면 안된다. 대신 이 자원(혹은 자원을 만드는 팩토리)을 해당 클래스를 인스턴스화 할 때 넘겨주자.
자원을 직접 명시하는 잘못된 예시 - 정적 유틸리티 & 싱글턴
맞춤법 검사기가 사전을 자원으로 가진다고 가정하자. 만약 사전을 직접 명시한다는 건 어떤 얘기일까?
1 2 3 4 5 6 7 8
//정적 유틸리티를 활용한 예제 publicclassSpellChecker{ privatestaticfinal Dictionary dictionary = new Dictionary(Language.ENGLISH); privateSpellChecker(){} //객체 생성 방지 publicstatic String changeSuggestions(String typo){...} }
1 2 3 4 5 6 7 8
//싱글톤을 활용한 예제 publicclassSpellChecker{ privatefinal Dictionary dictionary = new Dictionary(Language.ENGLISH); privatestatic SpellChecker INSTANCE = new SpellChecker(); privateSpellChecker(){} publicstatic String changeSuggestions(String typo){...} }
위 두 예시 모두 자원인 사전을 final로 직접 명시하고 있다.
나중에 다른 사전을 사용하고 싶을 때 변경이 힘들어진다.
final을 제거하고 사전을 교체하는 메서드를 추가하는 방식은 멀티스레드 환경에 쓸 수 없음.
즉 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식을 사용하면 안된다!