Builder 패턴이란 무엇일까?
현재 내 머릿속에 들어있는 Builder 패턴은 그냥 Lombok에서 제공해주는 어노테이션... 으로 객체를 생성할때 원하는 파라미터만 넣어서 만들수 있는 패턴? 방법? 으로 들어있다. 그러나 살짝만 검색해봐도 매우 잘못되게 알고있음을 알수있었다... 호돌맨의 요절복통 개발쇼를 보면서 매~일 SI회사에서 Setter로 뚝딱 처리하던 방법에서 벗어나 코드를 작성할수 있어야 할것 같다는 생각또한 강하게 든다.. 그럼 Builder패턴에 대해서 알아보자.
포스팅을 하면서 도달하고자 하는 목표
- Builder패턴의 정의
- 내가 알고있는 Builder패턴에 대한 수정
- 장점
- lombok말고 직접 짜보기
Builder패턴이란?
GoF 디자인 패턴 중 생성 패턴에 해당한다.
빌더 패턴은 복잡한 객체를 생성하는 클래스와 표현하는 클래스를 분리하여, 동일한 절차에서도 서로 다른 표현을 생성하는 방법을 제공한다.
잘못알고있던 Builder패턴에 대한 바로잡기
개인적으로 이 부분은 오히려 크게 잘못알고있었다는 생각은 들지 않는다.
장점 그대로, 생성자 패턴을 쓰자니 파라미터 추가될때마다 생성자 만들어줘야 하고, 파라미터가 많아지면 가독성이 떨어지니까.. '코드만 추가해서 편한게 쓰자' 에 부합하는 느낌이다. 그런데 내가 놓치고있던 부분은, 단순 편리함과 유연성을 넘어서서 '객체의 불변성'을 보장하는데에 있는것 같다.
사실 꼭 Builder패턴의 특성은 아닌것 같지만, 내가 항상 써왔던 Setter의남발(수정자패턴)은 객체의 불변성을 해치게 되어.. 변수를 final로 선언 혹은 Setter메소드를 만들지 않음으로써 객체의 불변성을 보장하고, Setter가 없다보니 생성자패턴은 너무 귀찮아서 빌더를 쓰는게 아닐까!...
Builder패턴의 장점
1. 필요한 데이터만 설정할 수 있음
2. 유연성을 확보할 수 있음
3. 가독성을 높일 수 있음
4. 변경 가능성을 최소화할 수 있음
음.. 1~3번은 정말 편리함을 위해서 인것 같고, 4번은 꼭 Builder패턴의 특성에 맞는건지는 모르겠다.
Builder패턴 직.접 짜보기 ㅎ
ㅎㅎ... 그냥 맨땅에 직접짜보는건 좀 그렇고, Lombok에서 어떻게 구현했는지 까보았다 ㅎㅎ..
인텔리제이의 프로젝트 탐색기로도 볼수있듯이, 컴파일 전후로 내부클래스(PostBuilder)가 생겼다.
그럼 실제 소스코드는 어떻게 변했는지 보도록 하자!!
Post 클래스의 소스코드다. 아직 컴파일전인 Java파일이다.
package com.example.hodolclone.entity;
import lombok.Builder;
@Builder
public class Post {
private String title;
private String content;
}
JVM컴파일러로 Java파일을 Class파일로 컴파일 한 이후의 소스코드다.
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.example.hodolclone.entity;
public class Post {
private String title;
private String content;
Post(final String title, final String content) {
this.title = title;
this.content = content;
}
public static Post.PostBuilder builder() {
return new Post.PostBuilder();
}
public static class PostBuilder {
private String title;
private String content;
PostBuilder() {
}
public Post.PostBuilder title(final String title) {
this.title = title;
return this;
}
public Post.PostBuilder content(final String content) {
this.content = content;
return this;
}
public Post build() {
return new Post(this.title, this.content);
}
public String toString() {
return "Post.PostBuilder(title=" + this.title + ", content=" + this.content + ")";
}
}
}
그리고 보통 Builder패턴을 사용해 객체를 생성할때는 아래코드 처럼 사용한다.
Post post = Post.builder()
.content("content")
.title("title")
.build();
- Static메소드로 Post객체의 builder()메소드를 선언한다. 그래야 객체생성을 하지않고, 메소드를 불러올 수 있다.(객체생성을 하려는 메소드인데 객체를 생성해야 호출 할 수있으면... 뭔가 모순이...)
- Post.builder() 메소드로 내부클래스인 PostBuilder 객체를 생성,반환한다.
- 이후 PostBuilder객체의 메소드인 content(),title()을 사용해 PostBuilder 객체 내부에 값을 설정한다.
- 마지막 PostBuilder 객체의 build()메소드로 Builder객체가 가지고 있던 속성값을 갖는 Post객체를 반환한다!
내가 봤을때는 Builder패턴은 이정도로 코드로 구현되어있음을 확인하고, 이해하면 될 것 같다.
-끝!-
refs
https://4z7l.github.io/2021/01/19/design_pattern_builder.html
https://mangkyu.tistory.com/163
'프로그래밍 > Java' 카테고리의 다른 글
Spring Data JPA 간략 사용법! (1) | 2022.09.23 |
---|---|
Java GC 1차개정본 (0) | 2022.06.25 |
Dynamic Proxy 직접 구현해보기-2 (0) | 2021.08.10 |
Dynamic Proxy직접 구현해보기-1 (0) | 2021.08.10 |
Comparator의 동작방식 (0) | 2021.07.27 |