Skip to content

Commit

Permalink
feat: EffectiveJavaItem5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
Browse files Browse the repository at this point in the history
  • Loading branch information
02ggang9 committed Oct 8, 2023
1 parent 364accc commit 90d7dfc
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 23 deletions.
23 changes: 0 additions & 23 deletions _posts/java/2023-10-07-EffectiveJavaItem4.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ categories:
- Java
---



## Abstract를 쓰면 안되는 이유
상속받은 클래스로 인스턴스를 생성할 수 있고 잘못된 의도를 전달할 수 있습니다.

Expand Down Expand Up @@ -50,24 +48,3 @@ public class UtilityClass {
}
}
~~~


왜하면 상속 받으면 뚫림.

abstract를 써서 상속을 해서 써야하나? 라는 착각을 만들 수 있는 여지가 있다.

그래서 private로 생성자를 막아두자!

super에 있는 생성자를 더 이상 호출할 수 없으니까 상속 자체가 막히게 된다.

throw new AssertionError(); 를 써서 막아야 함. -> 예외를 처리하기 위한게 아니라 만나면 안되는 상황임. 혹시라도 이 상황을 만난다면 무조건 에러다! 이 생성자는 쓰이면 안된다. 라는 메시지임.

단점 -> 몼쓰게 만들려고 왜 코드를 만들지?

유틸리티 클래스??

스프링에서 유틸리티 클래스를 abstract로 해놓았는데 이러면 생성자가 뚫릴 수 있음.




70 changes: 70 additions & 0 deletions _posts/java/2023-10-07-EffectiveJavaItem5.md
Original file line number Diff line number Diff line change
@@ -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<String> suggestions(String typo) {
return dictionary.closeWordsTo(typo);
}
}
~~~

## 문제점 해결 - 의존 객체 주입 사용
인터페이스를 정의하고 외부에서 의존 객체를 주입하도록 코드를 변경하면 위의 두 가지 문제점을 해결할 수 있습니다. 테스트 할 때 모킹 객체를 주입해 테스트 시간을 단축할 수 있고 DefaultDictionary에서 KoreanDictionary로 변경할 때 SpellChecker 클래스의 코드를 변경하지 않아도 됩니다. 이는 OCP 원칙을 위반하지 않습니다.

~~~java
public interface Dictionary {

boolean contains(String word);

List<String> 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<String> suggestions(String typo) {
return dictionary.closeWordsTo(typo);
}
}

~~~

의존성이 수천 개나 되는 큰 프로젝트에서는 코드를 어지럽게 만들기도 합니다. 하지만 대표적으로 스프링 같은 의존 객체 주입 프레임워크를 사용하면 손쉽게 해결할 수 있습니다.

## 마치며
이펙티브 자바의 "자원을 직접 명시하지 말고 의존 객체 주입을 사용하라" 챕터를 살펴봤습니다. 끝에 스프링 프레임워크에 대해서 언급을 했는데 다음 포스트는 스프링 IoC에 대해서 살펴보겠습니다.

0 comments on commit 90d7dfc

Please sign in to comment.