[이펙티브 자바] 아이템5

hyng·2022년 11월 23일
0

이펙티브 자바

목록 보기
5/13

자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다.

Dictionary 클래스를 이용해서 맞춤법 검사를 하는 SpellChecker라는 클래스가 있다고 할 때,
SpellChecker는 어떤 요청에 대해서도 항상 동일한 결과를 반환하므로 정적 유틸리티 클래스나 싱글턴으로 구현하는 것을 생각할 수 있다.

정적 유틸리티로 구현

싱글턴으로 구현

그런데 만약 EngDictionary를 사용한다고 하면 의존성을 어떻게 바꿀 수 있을까?

단순하게 SpellChecker에서 new로 생성해 주던 KoDictionary를 EngDictionary로 바꿔주면 된다.

하지만 이후에 195개의 나라에 대한 사전이 생성되고 의존관계가 바뀐다면?
SpellChecker의 코드도 매번 변경되어야 한다. 그래서 이번엔 setter 메서드를 생성해 보았다.

사용하는 자원에 따라 동작이 달라지는 클래스를 정적 유틸리티 클래스로 생성하는 것은 적절하지 않다.

사전이 바뀔 때마다 setter 메서드를 호출해 주긴 해야 하지만 SpellChecker의 코드는 변경되지 않는다.

하지만 setter 메서드로 인해 여러 변경사항이 생겼다. final 키워드를 사용할 수 없게 되었고 setter가 public으로 열려있기 때문에 언제든지 의존관계가 변경될 수 있게 되었다.

해결 방법은 SpellChecker가 구현체가 아닌 인터페이스에 의존하도록 하고 실제 구현체는 외부에서 주입받도록 하여 새로운 사전이 생기더라도 SpellChecker의 코드는 변경되지 않도록 하는 것이다. 그리고 생성자를 통해 의존성을 주입받도록 하면 final 키워드를 사용하여 의존관계가 처음 객체 생성 시점 이후에 변경되지 않도록 할 수 있다.

클래스가 내부적으로 하나 이상의 자원에 의존하고, 그 자원이 클래스 동작에 영향을 준다면 싱글턴과 정적 유틸리티 클래스는 사용하지 않는 것이 좋다. 이 자원들을 클래스가 직접 만들게 해서도 안된다. 대신 필요한 자원을(혹은 그 자원을 만들어주는 팩터리를) 생성자에 (혹은 정적 팩터리나 빌더에) 넘겨주자.

profile
공부하고 알게 된 내용을 기록하는 블로그

0개의 댓글