OOP의 핵심은 한마디로 정리하면 재사용성, 재활용성이라 하여도 무방하다.
이 프로그래밍 패러다임을 구현하기 위해 고안된 것이 다양한 패턴인데, 그 중 "of"로 많이 알려져있는 정적 팩토리 패턴에 대해 좀 더 깊게 알아본 내용을 기록한다.
일단, 왜 "정적" 팩토리 메소드인가? 왜 static 인자를 생성자를 만들때 활용하는 것인가?
어차피 DTO는 데이터 전달을 위한 목적, 즉 상태 전달이 목적이지 저장이 목적이 아닌데, 굳이 DTO를 팩토리 패턴을 통해 생성하고 DTO의 전달성 데이터를 저장하는 과정이 필요한지 의문이 들었다.
이를 다시 말하면 특정 클래스에 종속되어 있다는 뜻이기도 하며, 어떠한 정보를 특정 클래스를 기반으로 확보하겠다는 의미도 내포한다.
즉, 객체 인스턴스를 생성하지 않고도 클래스 자체에서 생성자를 생성하고 객체나 정보를 호출할 수 있다는 점이 정적(static) 팩토리 개념의 출발점이다.
예를 들어
public class UserDTO {
private String name;
private int age;
// 정적 팩토리 메서드
public static UserDTO of(String name, int age) {
UserDTO dto = new UserDTO();
dto.name = name;
dto.age = age;
return dto;
}
}
이라는 DTO가 있다고 하자.
이전까지는 단순 데이터를 전달받는 목적, DTO의 getter, setter를 통해 특정 필드 혹은 항목에 대해서만 값을 전달받을 수 있다는 의미로만 활용하였다.
이제는 정적 팩토리 패턴을 통해, DTO의 특정 필드를 얻기 위해 불필요하게 진행하였던 객체 생성, 혹은 필드값 하나를 얻기 위해 비효율적으로 진행하였던 과정을 안해도 된다.
DTO 그 자체를 얻기 위한 방법을 알게된 것이다.
위에서 UserDTO.of(...)는 객체를 만들기 위한 메서드인데, static이니까 new UserDTO()처럼 객체를 먼저 만들지 않고 바로 호출 가능하다.
근데 왜 DTO는 정적이어야 하는가?
OOP 관점에서 유리하고 명확한 로직 구성이 가능해진다.
생성자보다 의미 있는 이름(of, from, with...)을 붙일 수 있어서 코드 가독성이 좋아진다. 사실 of는 많이 사용하는 단어일 뿐, 개발 상황에 따라 다양하게 사용가능하다.
가장 중요하다. 필요에 따라 캐싱, 서브클래싱, 조건 분기 등도 할 수 있고, 위에서 말한대로 불필요한 객채생성과정을 제거하고 효율적인 구성이 가능하다.
private 생성자 + static method로 외부에서 직접 생성 못 하게 제한 가능한데, DTO에서 getter/setter를 통해 아무 생각없이 상태값을 전달받고 수정할 수 있었던 것이 정적 팩토리 패턴을 통해 비교적 안전하게 진행 가능해졌다.
핵심은 인스턴스 메서드가 아니라 클래스 레벨에서 객체를 생성하기 위한 도구이고, OOP에 부합하기 위한 좋은 방법이다.
일반 메서드처럼 인스턴스를 먼저 만들어야 했다면, 객체를 만들기 위해 객체가 먼저 필요하다는 모순이 생겨버리는 것이 아닐까?
결국 정적 팩토리 메서드는 인스턴스를 만들기 위한 방법인데, 객체가 없으니까 클래스 레벨에서 호출할 수 있게 static으로 정의되는 것.