<aside> 1️⃣ 개념설명
</aside>
Spring Framework
**에서는 Dependency Injection (DI)
패턴을 사용하여 객체 간의 의존성을 관리한다. 이 패턴을 사용하면, 객체를 직접 생성하는 대신 Spring 컨테이너에 의해 생성된 객체(빈)를 주입받아 사용할 수 있다. 이로 인해 코드는 더욱 유연해지고 테스트하기 쉬워진다.<aside>
2️⃣ 객체 인스턴스를 new
키워드로 직접 생성하는 방식과 DI로 주입받는 방식의 차이점
</aside>
new
키워드를 사용하면, 객체 생성의 책임이 해당 코드에 있다. 반면에 DI를 사용하면, 객체 생성의 책임이 Spring 컨테이너에 있다. 이로 인해 코드는 객체 생성에 대한 세부 사항을 알 필요가 없으며, 대신 인터페이스에 의존할 수 있다.new
키워드를 사용하면, 해당 객체와 강하게 결합되므로 테스트하기 어렵다. 반면에 DI를 사용하면, 테스트 시에 실제 객체 대신 모의 객체(mock object)를 주입할 수 있으므로 테스트하기 쉽다.new
키워드를 사용하면, 해당 코드는 특정 구현에 의존하게 된다. 반면에 DI를 사용하면, 코드는 인터페이스에 의존하므로 구현을 쉽게 변경할 수 있다.new
키워드를 사용하여 직접 생성할 수 있다.<aside> 3️⃣ 그럼 컬렉션 타입은 new로 생성해도 괜찮은가?
</aside>
내가 만든 클래스가 아니라 이미 존재하던 HashMap<K,V>
or **new ArrayList<>()
**라던지 이런 컬렉션 타입이라면?
HashMap
, **ArrayList
**와 같은 Java의 표준 컬렉션 클래스들은 상태를 가지지 않는 유틸리티 클래스나 도메인 객체와 같이 생명주기를 Spring 컨테이너가 관리할 필요가 없는 객체들이다. 이런 경우에는 new
키워드를 사용하여 직접 생성하는 것이 일반적이다.그럼 이런 컬렉션 타입의 클래스들은 메소드의 매개변수에 선언해서 그 변수명을 메서드 내부에서 가져다 사용하는게 좋은가? 아니면 메서드 내부에서 new로 컬렉션 타입의 객체를 생성해서 사용하는게 좋은가?
예시코드를 보자
// nameList에 값을 넣어서 save()메소드로 리스트의 값을 저장하는 컨트롤러 로직이다.
@ResponseBody
@GetMapping("/)
public String getPage(List<String> nameList) {
nameList.add("data1");
nameList.add("data2");
userService.save(nameList);
return "ok";
}
nameList
**를 메서드의 매개변수로 받는 것이 아니라, 메서드 내부에서 **new ArrayList<>();
**를 사용하여 **nameList
**를 생성하는 것이 더 적절하다.
nameList
**는 getPage
메서드 내부에서만 사용되며, 이 메서드의 사용자가 **nameList
**를 제공할 필요가 없기 때문이다. 또한, **nameList
**를 메서드의 매개변수로 받으면, 이 메서드의 사용자가 **nameList
**의 상태에 대해 알아야 하므로 메서드의 사용성이 저하될 수 있다.@ResponseBody
@GetMapping("/")
public String getPage() {
// new가 보기싫어도 얘들은 이렇게 작성하는게 좋다고 한다.
List<String> nameList = new ArrayList<>();
nameList.add("data1");
nameList.add("data2");
userService.save(nameList);
return "ok";
}
getPage
메서드는 **nameList
**의 생성과 관리를 스스로 담당하며, 이 메서드의 사용자는 **nameList
**에 대해 알 필요가 없다. 이로 인해 코드가 더 간결하고 명확해진다.<aside> 4️⃣ 컬렉션 타입은 new로 생성해도 괜찮은가? - 결론
</aside>
new
키워드를 사용하여 컬렉션을 직접 생성하는 것이 더 간결하고 명확하다. 또한, 이렇게 하면 메서드의 사용자는 메서드가 어떤 컬렉션을 사용하는지 알 필요가 없으므로 메서드의 사용성이 향상된다.