[디자인 패턴] 빌더 패턴(Builder Pattern)

Aug 18, 2024
[디자인 패턴] 빌더 패턴(Builder Pattern)

1. 빌더 패턴

객체 생성 패턴 중 하나로, 복잡한 객체를 단계별로 생성할 수 있도록 도와준다. 이 패턴은 특히 생성자나 정적 팩토리 메서드에 많은 매개변수가 필요할 때 유용하다.
아래에 나열된 아이들은 단순히 데이터를 들고 있는 아이들로, 데이터 덩어리, 클래스 자료를 만들었다 생각하면 된다. 이건 객체라고 생각하지 않는다.
 
private int id; private String name; private int age; private String email;
 
DB에서는 테이블을 릴레이션(Relation)이라고 부르며, 설계 과정에서는 이를 엔티티(Entity)로 표현하는데, 자바에서는 테이블과 동일한 내용물이라면 이를 엔티티(Entity)라고 부른다.
VO(Value Object)는 엔티티와 달리 식별자가 필요 없는 값 자체를 표현하는 객체를 의미한다.
 

1-1. 빌더 패턴 적용 전

 
notion image
 
new Person() 을 만든 다음에 시간이 지나서 set 할 필요가 없다. 바로 만들어보자.
 
package ex09; public class Person { private int id; private String name; private int age; private String email; public Person(int id, String name, int age, String email) { this.id = id; this.name = name; this.age = age; this.email = email; } }
public class App { public static void main(String[] args) { Person p1 = new Person(1, "홍길동", 20, "ej@nate.com"); } }
 
위와 같이 순서 맞춰서 p1 을 만들면 될 것 같지만, 아래와 같이 타입(String, int)만 맞추고 순서를 바꿔도 에러가 나지 않는 문제점이 있다.
 
notion image
 
 

1-2. 빌더 패턴 적용해보기

💡
static 붙여놓으면 new 하기 전에 메모리에 뜬다.
클래스별로 .class 해서 static 공간에 뜰 것
 
생성자 접근제한자를 private 으로 바꾸면 다른 클래스에서 new 생성할 수 없다.
heap 공간에 Person 이 올라가고, 외부에서 Person.builder() 를 통해 객체에 접근 가능하게 만든다.
notion image
notion image
notion image
notion image
 
빌더는 뜻 그대로 계속해서 쌓아나가는 것. 계속 짓는 것으로 보면 된다.
 
notion image
 
아래와 같이 빌더 패턴을 적용하면,
코드를 짤 때 가독성이 좋고, 실수가 적어진다는 장점이 있다.
 
notion image
 
빌더 패턴 적용 전에 생성자를 만들어서 쓸 때에는 ex. id만 넣고 싶다면 오버로딩을 해야됐지만,
빌더 패턴을 사용하면, 순서 상관없고, 수 안하고, 내가 넣고싶은거 오버로딩 하지 않아도 된다.
빌더를 사용하는게 생성자를 사용하는 것보다 훨씬 나은 방법.
 
하지만 여기서 끝난게 아니다.

2. 적용

 
getter 를 사용하여, 빌더 패턴이 잘 적용 되었는지 확인해보자.
 
package ex09; public class Person { private int id; private String name; private int age; private String email; private Person() {} public static Person builder() { return new Person(); } public Person id(int id) { this.id = id; return this; } public Person name(String name) { this.name = name; return this; } public Person age(int age) { this.age = age; return this; } public Person email(String email) { this.email = email; return this; } public int getId() { return id; } public String getName() { return name; } public int getAge() { return age; } public String getEmail() { return email; } }
 
int 값을 넣지 않고, 출력했을 때 null 이 나와야 하는데, 0 이 출력된다.
 
package ex09; public class App { public static void main(String[] args) { Person p1 = Person.builder().id(1).name("홍길동").email("ej@nate.com"); System.out.println(p1.getAge()); } }
notion image
 
나이가 등록된 값이 없으면 null 이 나와야 하는데, ex. 돈이 왔다갔다하는 money 일 때 0 이 나오면 큰 일 인 것과 같음..
 
그러니 타입을 int 가 아닌 Integer 로 바꿔서 사용하자.
 
package ex09; public class Person { private Integer id; private String name; private Integer age; private String email; private Person(){} public static Person builder(){ return new Person(); } public Person id(Integer id){ // person 객체가 heap 에 뜸 this.id = id; // this 가 heap 임, p1은 외부에서 정한 이름이니 나를 지칭할 수 없잖아 그래서 this 사용 heap 에 그 주소 그대로 다시 리턴 return this; } public Person name(String name){ this.name = name; return this; } public Person age(Integer age){ this.age = age; return this; } public Person email(String email){ this.email = email; return this; } public Integer getId() { return id; } public String getName() { return name; } public Integer getAge() { return age; } public String getEmail() { return email; } }
package ex09; public class App { public static void main(String[] args) { Person p1 = Person.builder().name("홍길동").email("ej0000@nate.com"); System.out.println(p1.getAge()); } }
 
null 로 잘 출력되는 것을 확인 할 수 있다.
notion image
 
굿.
 
Share article

eunmouse