diff --git a/_posts/java/2023-10-07-EffectiveJavaItem4.md b/_posts/java/2023-10-07-EffectiveJavaItem4.md index f9bde99e..8ec145ea 100644 --- a/_posts/java/2023-10-07-EffectiveJavaItem4.md +++ b/_posts/java/2023-10-07-EffectiveJavaItem4.md @@ -5,8 +5,6 @@ categories: - Java --- - - ## Abstract를 쓰면 안되는 이유 상속받은 클래스로 인스턴스를 생성할 수 있고 잘못된 의도를 전달할 수 있습니다. @@ -50,24 +48,3 @@ public class UtilityClass { } } ~~~ - - -왜하면 상속 받으면 뚫림. - -abstract를 써서 상속을 해서 써야하나? 라는 착각을 만들 수 있는 여지가 있다. - -그래서 private로 생성자를 막아두자! - -super에 있는 생성자를 더 이상 호출할 수 없으니까 상속 자체가 막히게 된다. - -throw new AssertionError(); 를 써서 막아야 함. -> 예외를 처리하기 위한게 아니라 만나면 안되는 상황임. 혹시라도 이 상황을 만난다면 무조건 에러다! 이 생성자는 쓰이면 안된다. 라는 메시지임. - -단점 -> 몼쓰게 만들려고 왜 코드를 만들지? - -유틸리티 클래스?? - -스프링에서 유틸리티 클래스를 abstract로 해놓았는데 이러면 생성자가 뚫릴 수 있음. - - - - diff --git a/_posts/java/2023-10-07-EffectiveJavaItem5.md b/_posts/java/2023-10-07-EffectiveJavaItem5.md new file mode 100644 index 00000000..6fb022bb --- /dev/null +++ b/_posts/java/2023-10-07-EffectiveJavaItem5.md @@ -0,0 +1,70 @@ +--- +published: true +title: "Effective Java Item 5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라" +categories: + - Java +--- + +## 자원을 직접 명시할 경우 생길 수 있는 문제점 +자원을 직접 명시할 경우 생기는 문제점은 아래의 두 가지 입니다. + +1. 테스트 하기 어렵다. +2. 코드가 유연하지 않다. + +테스트할 때 모킹하기가 어렵습니다. 그리고 Dictionary에서 DefaultDictionary, KoreanDictionary 처럼 사용할 리소스가 변경될 경우 클라이언트 코드를 변경해야 합니다. 이는 OCP(확장에는 열려있고 변경에는 닫혀야 한다)를 위반합니다. + +~~~java +public class SpellChecker { + + // 자원을 직접 명시한다 -> new DefaultDictionary(), new KoreanDictionary() + private static final Dictionary dictionary = new Dictionary(); + + // private 생성자로 외부에서 인스턴스 생성을 차단 + private SpellChecker() {} + + public static boolean isValid(String word) { + return dictionary.contains(word); + } + + public static List suggestions(String typo) { + return dictionary.closeWordsTo(typo); + } +} +~~~ + +## 문제점 해결 - 의존 객체 주입 사용 +인터페이스를 정의하고 외부에서 의존 객체를 주입하도록 코드를 변경하면 위의 두 가지 문제점을 해결할 수 있습니다. 테스트 할 때 모킹 객체를 주입해 테스트 시간을 단축할 수 있고 DefaultDictionary에서 KoreanDictionary로 변경할 때 SpellChecker 클래스의 코드를 변경하지 않아도 됩니다. 이는 OCP 원칙을 위반하지 않습니다. + +~~~java +public interface Dictionary { + + boolean contains(String word); + + List closeWordsTo(String typo); +} +~~~ + +~~~java +public class SpellChecker { + + private final Dictionary dictionary; + + private SpellChecker(Dictionary dictionary) { + this.dictionary = dictionary; + } + + public boolean isValid(String word) { + return dictionary.contains(word); + } + + public List suggestions(String typo) { + return dictionary.closeWordsTo(typo); + } +} + +~~~ + +의존성이 수천 개나 되는 큰 프로젝트에서는 코드를 어지럽게 만들기도 합니다. 하지만 대표적으로 스프링 같은 의존 객체 주입 프레임워크를 사용하면 손쉽게 해결할 수 있습니다. + +## 마치며 +이펙티브 자바의 "자원을 직접 명시하지 말고 의존 객체 주입을 사용하라" 챕터를 살펴봤습니다. 끝에 스프링 프레임워크에 대해서 언급을 했는데 다음 포스트는 스프링 IoC에 대해서 살펴보겠습니다. \ No newline at end of file