이게 무슨소리야?
조금 풀어서 말하면 클래스가 내부적으로 하나 이상의 자원에 의존한다면 이 자원들을 직접 만들게 해서는 안된다는 말이다.
그러면 자원은 어떻게 만들지? 라는 의문이 들것이다.
자원을 직접 생성하는것이 아닌 생성자(+ 빌더, 정적 팩토리 메소드)에 넘겨준다.
글로만 보아서는 이해가 어려울수도 있다. (필자가 그랬다...)
그래서 간단한 예제를 만들어 보았다.
시나리오
- 한국어 사전이 있다.
- 한국어 맞춤법 검사를 지원한다.
위와같은 시나리오에서 클래스 내부에서 new 연산자를 이용하여 생성한다면 어떻게 코드를 작성하겠는가?
아마도 대부분 아래와 같이 작성할것이다.
한국어 사전.Class
public class KoreaLexicon {
public KoreaLexicon() {
}
}
맞춤법 검사기.Class
public class SpellChecker {
private KoreaLexicon korea = new KoreaLexicon();
}
위와같이 작성한다면 문제가 없을까?
당장은 발생하지 않을것이다.
문제는 회사가 "우리는 이제 영어사전과 영어 맞춤법 검사도 지원합니다" 라고 하면 어떻게 되는가 ?
영어사전.Class 를 아래와 같이 작성했다.
public class EnglishLexicon{
public EnglishLexicon() {
}
}
맞춤법 검사기 클래스는 어떻게 할것인가?
한국어 맞춤법 검사기 클래스처럼 또 맞춤법 검사기 클래스를 작성할 것인가?
좋다. 그러면 일본어가 추가된다, 중국어가 추가된다, 불어가 추가된다 그때마다 2개의 클래스를 작성할 것인가?
우리는 이 문제를 클래스 내부에서 직접 생성하는것이 아닌 생성자(+빌더, 정적 팩토리 메소드)에 넘겨받음으로써 간단히 해결 할 수 있다. (이것을 의존성 역전이라고 한다)
사전 인터페이스를 만들고 각 언어사전은 사전 인터페이스를 구현한다.
public class KoreaLexicon implements Lexicon {
public KoreaLexicon() {
}
}
public class EnglishLexicon implements Lexicon{
public EnglishLexicon() {
}
}
맞춤법검사기 클래스는 new 연산자를 이용해 직접 생성하는게 아닌 생성자를 통해 인터페이스를 넘겨받는다.
public class SpellChecker {
private Lexicon lexicon;
public SpellChecker(Lexicon lexicon) {
this.lexicon = lexicon;
}
사용하는 입장에서는 사용할 사전을 생성하여 맞춤법검사기 클래스에 넘겨주기만 하면된다.
public final class main {
public static void main(String[] args) {
Lexicon KoreaLexicon = new KoreaLexicon();
SpellChecker koreaSpellChecker = new SpellChecker(KoreaLexicon);
Lexicon englishLexicon = new EnglishLexicon();
SpellChecker englishSpellChecker = new SpellChecker(englishLexicon);
}
}
이렇게 하면 뭐가좋지?
- 클래스의 유연성 및 재사용성이 증가한다.
위에서 보았듯이 하나의 클래스를 이용하여 맞춤법 검사를 할 수 있다. - 의존성을 느슨하게 하며 코드변경을 최소화 할 수 있다.
new 연산자를 한다면 한국 맞춤법검사기는 한국어만 영어 맞춤법검사기는 영어만 할 수 있다.
하지만 위와같은 방식으로 진행하면 맞춤법검사기는 여러가지 사전(클래스)를 받을 수 있다.
어떠한 언어가 추가될 때 사전규격만 맞으면 되므로 의존성이 줄어드며 기존코드에 영향이 없으므로 코드변경이 최소화된다.
위와같은 방법을 쓰는 대표적인 프레임워크는 Spring Framework이다.
출처 : effective java 3/E
'개발 > JAVA' 카테고리의 다른 글
[effective java 3/E] 상속보다는 컴포지션을 사용하라 (0) | 2020.07.05 |
---|---|
[effective java 3/E] equals는 일반 규약을 지켜 재정의하라. (0) | 2020.07.05 |
[effective java 3/E] private 생성자나 열거타입으로 싱글턴임을 보증하라 (0) | 2020.06.26 |
[effective java 3/E] 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2020.06.21 |
[effective java 3/E] 생성자 대신 정적 팩터리 메서드를 고려해보자 (0) | 2020.06.21 |
댓글