Builder

객체를 생성할 때 흔하게 사용하는 패턴

Member member = Member.builder()
	.name("SUN")
	.age("32")
	.build();

//이런 패턴을 Dot(.) Chain문법이라고 부른다.

GoF-Design-Pattern (1994년)

  • 객체의 생성 알고리즘과 조립 방법을 분리하는 것이 목적

이펙티브 자바 (2001년)

  • 코드 읽기/유지보스가 편해지므로 빌더 패턴을 쓰라고 한다.
  • 객체 일관성, 변경 불가능성 등의 특징

규칙) 생성자 인자가 많을 때는 빌더 패턴 적용을 고려. ➜ 객체 생성을 깔끔/유연하게 하기 위한 기법


  • 생성자 인자가 많을 때 불편한 예시
package step1;

import java.time.LocalDate;

public class Person {
	
	private String firstName;
	private String lastName;
	private LocalDate birthDate;
	private String addressOne;
	private String addressTwo;
	private String sex;
	private boolean driverLicence;
	private boolean married;
	
	//아래처럼 생성자를 만들경우, 일부값만 초기화 하고싶어지는 케이스가 많아질수록 불편해진다. 
	/*
	 * public Person(String firstName, String lastName, LocalDate birthDate, String
	 * addressOne, String addressTwo, String sex, boolean driverLicence, boolean
	 * married) { super(); this.firstName = firstName; this.lastName = lastName;
	 * this.birthDate = birthDate; this.addressOne = addressOne; this.addressTwo =
	 * addressTwo; this.sex = sex; this.driverLicence = driverLicence; this.married
	 * = married; }
	 * 
	 * public Person(String firstName, String lastName) { super(); this.firstName =
	 * firstName; this.lastName = lastName; }
	 */

	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public LocalDate getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(LocalDate birthDate) {
		this.birthDate = birthDate;
	}
	public String getAddressOne() {
		return addressOne;
	}
	public void setAddressOne(String addressOne) {
		this.addressOne = addressOne;
	}
	public String getAddressTwo() {
		return addressTwo;
	}
	public void setAddressTwo(String addressTwo) {
		this.addressTwo = addressTwo;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public boolean isDriverLicence() {
		return driverLicence;
	}
	public void setDriverLicence(boolean driverLicence) {
		this.driverLicence = driverLicence;
	}
	public boolean isMarried() {
		return married;
	}
	public void setMarried(boolean married) {
		this.married = married;
	}
}
package step1;

public class TestPattern {

	public static void main(String[] args) {
		Person p1 = createPersonForTesting();
		System.out.println(p1.getFirstName());

	}
	
	public static Person createPersonForTesting() {
		
		Person person = new Person();
		person.setFirstName("FirstName");
		person.setLastName("LastName");
		person.setAddressOne("Address1");
		person.setAddressTwo("Address2");
		person.setSex("Man");
		person.setDriverLicence(false);
		person.setMarried(true);
		//멤버변수가 많다면 변수에 값 세팅이 어려워진다.
		
		return person;
	}

}

  • 구현 예제
package step2;

import java.time.LocalDate;
import java.time.Month;

public class TestPattern {

	public static void main(String[] args) {
		
		Person p1 = Person.builder()
				.FirstName("SUN")
				.LastName("Jung")
				.AddressOne("Seoul")
				.AddressTwo("Korea")
				.BirthDate(LocalDate.of(1989, Month.APRIL, 6))
				.Sex("female")
				.DriverLicence(true)
				.Married(false)
				.build();
		
		System.out.println(p1.getBirthDate());
	}
}
package step2;

import java.time.LocalDate;

public class Person {
	
	private String firstName;
	private String lastName;
	private LocalDate birthDate;
	private String addressOne;
	private String addressTwo;
	private String sex;
	private boolean driverLicence;
	private boolean married;
	

	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public LocalDate getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(LocalDate birthDate) {
		this.birthDate = birthDate;
	}
	public String getAddressOne() {
		return addressOne;
	}
	public void setAddressOne(String addressOne) {
		this.addressOne = addressOne;
	}
	public String getAddressTwo() {
		return addressTwo;
	}
	public void setAddressTwo(String addressTwo) {
		this.addressTwo = addressTwo;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public boolean isDriverLicence() {
		return driverLicence;
	}
	public void setDriverLicence(boolean driverLicence) {
		this.driverLicence = driverLicence;
	}
	public boolean isMarried() {
		return married;
	}
	public void setMarried(boolean married) {
		this.married = married;
	}
	
	public static PersonBuilder builder() {
		return new PersonBuilder();
	}

}
package step2;

import java.time.LocalDate;

public class PersonBuilder {
	
	private String firstName;
	private String lastName;
	private LocalDate birthDate;
	private String addressOne;
	private String addressTwo;
	private String sex;
	private boolean driverLicence;
	private boolean married;
	
	public PersonBuilder FirstName(String firstName) {
		this.firstName = firstName;
		return this;
	}
	public PersonBuilder LastName(String lastName) {
		this.lastName = lastName;
		return this;
	}
	public PersonBuilder BirthDate(LocalDate birthDate) {
		this.birthDate = birthDate;
		return this;
	}
	public PersonBuilder AddressOne(String addressOne) {
		this.addressOne = addressOne;
		return this;
	}
	public PersonBuilder AddressTwo(String addressTwo) {
		this.addressTwo = addressTwo;
		return this;
	}
	public PersonBuilder Sex(String sex) {
		this.sex = sex;
		return this;
	}
	public PersonBuilder DriverLicence(boolean driverLicence) {
		this.driverLicence = driverLicence;
		return this;
	}
	public PersonBuilder Married(boolean married) {
		this.married = married;
		return this;
	}
	
	public Person build() {
		
		Person person = new Person();
		person.setFirstName(firstName);
		person.setLastName(lastName);
		person.setBirthDate(birthDate);
		person.setAddressOne(addressOne);
		person.setAddressTwo(addressTwo);
		person.setSex(sex);
		person.setDriverLicence(driverLicence);
		person.setMarried(married);
		return person;
	}
}

//필요한 만큼만 세팅하면 된다. 다양한 생성자를 만들 필요가 없어지게 된다.

 

reference

인프런 강의 : 디자인패턴withJAVA