본문 바로가기
DesignPattern

[디자인패턴] Builder Pattern / 빌더패턴 구현

by 발개발자 2022. 9. 11.
반응형

  빌더(Builder) 패턴이란?

GoF 중 생성 패턴에 속하며, 객체를 생성할 때 유용하게 사용하는 디자인패턴이다.

기존에 생성자를 이용하여 객체를 생성하는데 생길 수 있는 문제를 보완하기 위해 사용되어 지며, 객체의 Optional한 속성이 많을수록 빌더패턴이 더욱 유용해진다.

 

아래와 같은 스타일로 객체를 생성하는 코드가 있다면, 빌더 패턴을 사용했다고 할 수 있다.

Member member = Member.builder()
.name("홍길동")
.age(30)
.build();

.으로 연속되게 이어지는 패턴을 Dot(.) Chain 문법이라고 부른다.

 

 

  빌더 패턴의 구조

Builder 

  • 객체를 생성하는데 사용되는 인터페이스이다.

 

ConcreteBuilder 

  • Builder를 실제로 구현하여 객체를 생성까지 담당하는 클래스이다.

 

Director 

  • ConcreteBuilder를 파라미터로 받아 디테일한 객체를 생성하고 반환해주는 클래스이다.

 

  예제

Builder - PersonBuilder

public interface PersonBuilder {
	public PersonBuilder firstName(String firstName) ;
	public PersonBuilder lastName(String lastName) ;
	public PersonBuilder birthDate(LocalDate birthDate) ;
	public PersonBuilder address(String address) ;
	public PersonBuilder sex(String sex) ;
	public Person build();
}

 

 

ConcreteBuilder - DefaultPersonBuilder

public class DefaultPersonBuilder implements PersonBuilder{
	private String firstName;
	private String lastName; 
	private LocalDate birthDate;
	private String address;
	private String sex;
	
	public DefaultPersonBuilder firstName(String firstName) {
		this.firstName = firstName;
		return this;
	}
	public DefaultPersonBuilder lastName(String lastName) {
		this.lastName = lastName;
		return this;
	}
	public DefaultPersonBuilder birthDate(LocalDate birthDate) {
		this.birthDate = birthDate;
		return this;
	}
	public DefaultPersonBuilder address(String address) {
		this.address = address;
		return this;
	}
	public DefaultPersonBuilder sex(String sex) {
		this.sex = sex;
		return this;
	}
	
	public Person build() {
		Person person = new Person();
		person.setFirstName(firstName);
		person.setLastName(lastName);
		person.setBirthDate(birthDate);
		person.setAddress(address);
		person.setSex(sex);
		return person;
	}

}

 

 

Director - PersonDirector

public class PersonDirector {
	private PersonBuilder personBuilder;
	
	public PersonDirector (PersonBuilder personBuilder) {
		this.personBuilder = personBuilder;
	}

	public Person teacher() {
		return personBuilder
				.firstName("최")
				.lastName("길동")
				.birthDate(LocalDate.of(1977, Month.AUGUST, 21))
				.address("서울시 관악구")
				.build();
	}
}

 

 

Main

public class Main {

	public static void main(String[] args) {
		  Person student = Person.builder()
				  .firstName("홍")
				  .lastName("길동")
				  .address("서울시 관악구")
				  .birthDate(LocalDate.of(1997, Month.AUGUST, 21))
				  .sex("Male")
				  .build();
		  
		  PersonDirector director = new PersonDirector(new DefaultPersonBuilder());
		  Person teacher = director.teacher();
		  
		  System.out.println("학생 : "  + student.toString());
		  System.out.println("선생님 : " + teacher.toString());

	}
}

 

결과

 

빌더패턴을 통해 객체를 유연하고 불변하게 생성하는 것을 확인할 수 있었다.

단일 객체를 다룰 때 Builder 인터페이스와 Director의 경우 불필요하게 코드량이 늘어나기 때문에 사용을 배제하기도 한다.

 

 

  장점 / 단점

장점

  • Setter를 사용하지 않기 때문에 한번의 함수 호출로 불변성을 유지한 객체를 생성할 수 있다.
  • 코드의 가독성과 유지보수성이 향상된다.
  • 유연성을 확보할 수 있다.

단점

  • 객체 수정이 불가능하기 때문에, 필요에 따라 새로운 객체를 계속 생성해야한다.

 

  실사용 사례

  • Java.net.http

HttpRequest

		String url = "https://api.upbit.com/v1/candles/minutes/";
		String param = minute + "?market=" + market + "&count=" + targetCount;
		HttpRequest request = HttpRequest.newBuilder()
			    .uri(URI.create(url + param))
			    .header("Accept", "application/json")
			    .method("GET", HttpRequest.BodyPublishers.noBody())
			    .build();

본인이 과거에 upbit api를 사용하기 위해 구현한 소스이다. 이렇듯 Builder 패턴은 특정 객체를 생성하기 위해 다양하게 활용되어 지고 있다.

 

오늘은 여기까지,,

끗!

반응형

댓글