이전에 쓴 코드들을 들여다보니 너무 기준 없이 사용하고 있음을 느껴서 다시 정리할 겸 대표적인 객체 생성 방법 3가지를 알아보려고 한다.
자세한 개념에 대해서는 잘 설명해 주는 글들이 많으니 넘어가고, 장단점과 함께 간단한 비교만 하겠다.
public class Post {
private String category; // a
private String title; // b
private String content; // c
//각 메서드들
}
인스턴스 변수에 각각 a, b, c를 집어넣은 객체를 생성하려고 한다. 같은 목표를 각자의 방식으로 구현한 뒤 차이점을 확인해 보자.
객체를 생성하는 3가지 방법
생성자
// 생성자
public Post(String category, String title, String content) {
this.category = category;
this.title = title;
this.content = content;
}
// 생성자를 통한 객체 생성
Post post = new Post("a", "b", "c");
생성자의 파라미터를 이용해 인스턴스 변수를 초기화 후 Post 객체를 생성한다.
장점
- 간단하고 직관적인 방법이다.
- 코드가 간결해서 일반적인 상황에서 쓰인다.
단점
- 가독성과 유지 보수성이 떨어진다.
정적 팩토리 메서드
// 정적 팩토리 메서드
public static Post createPost(String category, String title, String content) {
Post post = new Post();
post.category = category;
post.title = title;
post.content = content;
return post;
}
// 정적 팩토리 메서드를 통한 객체 생성
Post post = Post.createPost("a", "b", "c");
Post 클래스의 정적(static) 메서드로, 파라미터를 사용하여 설정된 Post 객체를 생성 후 반환하는 역할을 한다.
장점
- 명확한 네이밍으로 코드의 가독성을 상승시킨다.
- 하위 자료형을 반환할 수 있다.
- 객체 생성을 캡슐화 할 수 있다. (ex. DTO와 Entity간 형 변환)
단점
- 상속이 불가능하다.
- API의 학습 곡선이 높아진다.
빌더 패턴
// 빌더 클래스
public static class Builder {
private String category;
private String title;
private String content;
public Builder Category(String category) {
this.category = category;
return this;
}
public Builder Title(String title) {
this.title = title;
return this;
}
public Builder Content(String content) {
this.content = content;
return this;
}
public Post build() {
Post post = new Post();
post.category = this.category;
post.title = this.title;
post.content = this.content;
return post;
}
}
// 빌더 패턴을 사용한 객체 생성
Post post = new Builder()
.Category("a")
.Title("b")
.Content("c")
.build();
Post 클래스 내부에 Builder 클래스를 생성한다. Builder는 파라미터의 값을 입력하는 메서드를 갖고 있다.(=setXxx)
이 메서드들은 각각의 파라미터를 인스턴스 변수에 설정하고, 빌더 객체 자신을 반환하여 메서드 체인을 구성한다.
build 메서드는 실제 Post 객체를 생성하는 메서드다. Builder의 인스턴스 변수 값을 이용하여 Post 객체를 생성한다.
장점
- 매개변수가 많을 때 가독성이 좋다.
- 선택적 매개변수를 다루기 쉽다.
단점
- 코드가 복잡해진다.
- 롬복 사용하면 편해서 남발하게 된다.
정리
// 생성자를 통한 객체 생성
Post post = new Post("a", "b", "c");
// 정적 팩토리 메서드를 통한 객체 생성
Post post = Post.createPost("a", "b", "c");
// 빌더 패턴을 사용한 객체 생성
Post post = new Builder()
.Category("a")
.Title("b")
.Content("c")
.build();
객체 생성하는 코드만 떼어놓고 비교할 경우 가독성이 명확히 차이가 난다.
생성자는 파라미터 정보를 유추하기 힘들다.
정적 팩토리 메서드는 메서드 이름을 설정할 수 있기에 잘 설계한다면 알아보기 쉬울 것이다.
빌더 패턴은 가독성이 너무 좋다
생성자보단 정적 팩토리 메서드를 사용하고, 매개변수가 많을 경우 빌더 패턴을 이용하자.