티스토리 뷰

java

[Java] Builder Pattern

tonirr 2020. 4. 11. 18:48

이펙티브 자바 ITEM2를 보면서 빌더패턴이 무엇인지 이해가 잘 안되어서 강의를 찾아보게 되었다 

인프런 GoF 디자인패턴 with Java 강의를 참고 하였음

 

  • 빌더 패턴은 객체를 생성할 때 흔하게 사용하는 패턴
  • 자바로 코딩할 때 다음과 같은 스타일로 객체를 생성하는 코드가 있다면 빌더 패턴을 사용했다고 할 수 있음
    • 이러한 패턴을 Dot(.) Chain 문법이라 부른다.
Member customer = Member.builder()
	.name("홍길동")
    .age(30)
    .build();
  • GoF-Design-Pattern의 빌더 패턴(1994년)
    • 객체의 생성 알고리즘과 조립 방법을 분리하는 것이 목적
  • 이펙티브 자바(Effective-Java)의 빌더 패턴(2001년)
    • GoF의 빌더 패턴보다 좀 더 코딩 위주의 활용법을 설명
      • 코드 읽기/유지보수가 편해지므로 빌더 패턴을 쓰라고 함
    • GoF가 책을 썼을 때에는 상대적으로 덜 중요했던 객체 일관성, 변경 불가능성 등의 특징을 설명
    • 규칙. 생성자 인자가 많을 때에는 Builder 패턴 적용을 고려해 볼 것
    • ITEM 2. 생성자에 매개변수가 많다면 빌더를 고려할 것
      • 이펙티브 자바에서 말하는 빌더 패턴은 객체 생성을 깔끔하고 유연하게 하기 위한 기법
  • 빌더패턴을 사용하지 않는 경우
  1. 점층적 생성자 패턴
    • 필수 생성자를 만들기
    • 필수 인자들과 선택적 인자 1개를 받는 생성자 만들기
    • 필수 인자들과 선택적 인자 2개를 받는 생성자 만들기
    • 이러한 형식으로 점층적으로 생성자의 인자를 늘리는 방식으로 만듦
    • 장점
      • 필수 인자만 받아 객체를 생성할 수 있음
    • 단점
      • 인자가 추가되면 코드를 수정하기 어려움
      • 코드 가독성이 떨어짐
      • 인자의 수가 많은 경우 호출된 코드만 보아서는 의미를 알기 어려움
  2. 자바빈 패턴
    • 점층적 패턴의 대안으로 setter 메소드를 이용해서 생성코드를 읽기 좋게 만듦
    •  장점
      • 각 인자의 의미를 파악하기 쉬움복잡하게 여러 개의 생성자를 만들지 않아도 됨
    •  단점
      • 객체 일관성이 깨짐
        • 1회의 호출로 객체 생성이 끝나지 않음
        • 한번에 생성하지 않고 생성된 객체에 setter를 여러번 호출하여 값을 저장하고 있음
        • setter 메서드가 있어 변경 불가능한 클래스를 만들 수 없음
          • 스레드 안전성을 확보하려면 점층적 패턴보다 많은 일을 해야함

 

 

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("ListName");
		person.setAddressOne("Address1");
		person.setAddressTwo("Address2");
		person.setSex("Man");
		person.setDriverLicence(false);
		person.setMarried(true);
		// ... 멤버변수가 많다면 변수에 값 세팅이 어려워진다.
		return person;
	}
}

 

3. 빌더 패턴(Effective Java 스타일)

  • 장점
    • 각 인자가 어떤 의미인기 알기 쉬움
    • setter 메소드가 없어 변경 불가능 객체를 만들 수 있음
    • 한 번에 객체를 생성하여 객체의 일관성이 깨지지 않음
    • build() 함수가 잘못된 값이 입력되었는지 검증하게 할 수도 있음
  • PersonBuilder.java
    • 필수 인자가 있다면 먼저 필수요소를 포함한 생성자를 만듦
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.setAddressOne(addressOne);
		person.setAddressTwo(addressTwo);
		person.setBirthDate(birthDate);
		person.setSex(sex);
		person.setDriverLicence(driverLicence);
		person.setMarried(married);
		person.setMarried(married);
		return person;
	}
}
  • TestBuilder.java
    • Person 객체를 빌더패턴으로 구성하면 아래와 같이 main 메소드에서 chain 형식으로 사용 가능
public class TestPattern {

	public static void main(String[] args) {
		
		Person p1 = Person.builder()
					.firstName("FirstName")
					.lastName("LstName")
					.addressOne("금전구")
					.addressTwo("Addr2")
					.birthDate(LocalDate.of(1995, Month.APRIL, 13))
					.sex("male")
					.driverLicence(true)
					.married(true)
					.build();
		
		System.out.println(p1.getAddressOne());
	}
}

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함