티스토리 뷰
//사용방법
Book book = new Builder("MYBOOK").setContent("IT"),setAutor("JINSUB").build();
public class Book {
private String title;
private String content;
private String author;
public Book(String title) {
}
public void setTitle(String title) {
this.title = title;
}
public void setContent(String content) {
this.title = title;
}
//...이하 파라미터별 set함수
Vo Class 및 DTO Class를 설계할 때, 필요한 인자들을 선택적으로 받아야할 경우가 있다.(DB 필수(require) 엔티티)
이럴 때, 선택적으로 받야야할 인저를 위해 오버로딩하는 생성자 매개변수 조합이 많아진다.
예를 들면 ,
에서 생성자의 조합은 3*2*1 = 6개의 조합이 있다.
이는 인자가 하나가 늘어날 수록 생성자 숫자가 크게 늘어나고, 매개변수의 순서 및 자료형을 실수할 가능성이 크게 증가한다.
우선 코딩량이 매우 많아진다.
이에 대한 대안으로 나온 것이 자바빈즈(JAVA Beans)패턴이다.
public class Book {
private String title;
private String content;
private String author;
public Book(String title) {
this.title = title;
}
public Book(String title, String content) {
this.title = title;
this.content = content;
}
//...이하 파라미터 조합마다 생성자
Book book = new Book();
book.setTitle("MYBOOK");
book.setContent("IT");
//...사용방법
이렇게하면 코드량은 줄고 가독성이 좋아지지만 객체의 일관성이 깨지게된다.
외부에서 set함수를 통해 객체 내부 정보에 접근할 수 있다.
따라서 언제 어디서 해당 인스턴스 값들을 Set해줘야하는지 코드상에서 명확하게 구분하기 애매해진다.
(이 때 내부를 변경하기 위해서는 명확한 행동명의 함수를 만드는 것이 추천됨 ex. public void 책이름변경( ){ ... } )
또한 1회의 호출로 객체 생성이 끝나는 것이 아니라 여러번 호출하게 된다 .
따라서 마지막 최종진화형인 Builder 패턴을 사용할 수 있다.
public class Book{
private String title;
private String content;
private String author;
private Book(){
}
//빌더패턴
public static class Builder{
private String title;
private String content;
private String author;
//빌더의 생성자 !* title 필수 엔티티라고 가정 *!
public Builder(String title){
this.title = title; //필수 엔티티
}
public Builder setContent(String content){
this.cotent = content;
return this; //여기서 메서드 체이닝 가능
}
public Builder setAuthor(String author){
this.author = author;
return this;
}
//최종으로 빌드를 해주는 Builder내부함수;
public Book build(){
Book book = new Book();
book.title = title;
book.content = content;
book.author = author;
return book;
}
}
}
//사용
Boob book = new Book.Builder("mybook").setContent("IT").setAutor("JINUSB").build();
2번 자바 빈즈패턴과 차이점은 set함수에서 Book Class의 내부 클래스인 Builder Class로 리턴을 해준다 .
그리고 빌더 내부함수인 build()에서 book인스턴스를 리턴해준다.
만약
pubilc Example(Stirng a, String b){
this.a = a
this.b =b
}
일 경우 new example(b,a)처럼 실수가 있어도 코드 실행 전까지 문제를 찾을 수 없다.
빌더 패턴을 이용하면 new example.builder().set_a(a).set_b(b).build(); 처럼 명확하게 인지 가능한 객체지향적인 코드를 완성할 수 있다.
즉 VO클래스 내부에서 Builer객체를 하나 더 만들어서 메서드 체이닝으로 객체를 생성한다.
이렇게 하면 외부에서 객체 내부를 수정할 방법은 객체를 통해 클래스의 정보를 분석해 내는 프로그램 기법(리플렉션) 밖에 없다.(메세지)
단점은 객체를 하나 더 만들어서 때에 따라서는 성능이 낮아진다는 것 하지만 완벽하게 객체지향적인 패턴이다.
정리하자면
빌더 패턴은 객체지향적인 측면으로 별도의 Builder 클래스를 만들어 필수 값에 대해서는 생성자를 통해, 선택적인 값들에 대해서는 메소드를 통해 step-by-step으로 값을 입력받은 후에 build() 메소드를 통해 최종적으로 하나의 인스턴스를 리턴하는 방식
보기에 헷갈리지만 하나씩 따라가다보면 말이된다.
롬복에서 생성자 위에 @Builder 어노테이션 하나로 완성이 가능하다. 굳..
참고자료
'공부 > T.I.L(2021)' 카테고리의 다른 글
TIL - UX디자인 (0) | 2021.02.18 |
---|---|
TIL - 프로그래밍에서 Mocking이란? (0) | 2021.02.02 |
6. TIL - 도메인_프로그래밍에서 도메인이란 무엇일까? (0) | 2021.01.17 |
5.TIL - 신장트리, MST, 크루스칼, union-find (0) | 2021.01.14 |
4. TIL - 플러그인(plug-in), 빌드도구(그레이들) (0) | 2021.01.08 |