반응형
생성(construction)과 표기를 분리해 복잡한 객체를 생성한다.
별도의 Builder 클래스를 만들어 필수 값에 대해서는 생성자를, 선택적인 값에 대해서는 메소드를 통해 값을 입력 받은 후, build 메소드를 통해 하나의 인스턴스 리턴
- 선택적인(Optional) 멤버 변수, 파라미터나 지속성 없는 상태 값이 많을 때
- 팩토리 패턴에서 생성해야 하는 하위 클래스들이 복잡할 때
단점
- 매개변수가 적은 경우 생성자보다 코드가 장황해 진다.
구현 방법
- 빌더 클래스를 Static Nested Class로 생성
- nested class: 클래스 내부 클래스
public static class WalletBuilder {
// Required
private final int cash;
// Optional
private int creditCard;
private boolean identificationCard;
}
- 생성자는 public, 필수 값들에 대해 생성자의 파라미터로 받는다.
public WalletBuilder(int cash) { // Required
this.cash = cash;
}
- 선택적인(Optional)한 값들에 대해서 속성마다 메소드로 제공, 메소드의 리턴 값은 빌더 객체 자신
public WalletBuilder creditCard(int creditCard) { // Optional
this.creditCard = creditCard;
return this;
}
- 빌더 클래스 내에 build() 메소드를 정의하여 인스턴스를 리턴한다. build() 를 통해서만 객체를 생성하기 때문에 클래스의 생성자는 private으로 정의한다.
public Wallet build() { // build method
return new Wallet(this);
}
private Wallet(WalletBuilder builder) { // constructor
this.cash = builder.cash;
this.creditCard = builder.creditCard;
this.identificationCard = builder.identificationCard;
}
전체 코드
public class Builder {
public static void main(String[] args){
Wallet myWallet = new Wallet.WalletBuilder(1000)
.identificationCard(true)
.creditCard(200)
.build();
}
}
class Wallet {
private final int cash;
private int creditCard;
private boolean identificationCard;
private Wallet(WalletBuilder builder) {
this.cash = builder.cash;
this.creditCard = builder.creditCard;
this.identificationCard = builder.identificationCard;
}
public static class WalletBuilder {
// Required
private final int cash;
// Optional
private int creditCard;
private boolean identificationCard;
public WalletBuilder(int cash) {
this.cash = cash;
}
public WalletBuilder creditCard(int creditCard) {
this.creditCard = creditCard;
return this;
}
public WalletBuilder identificationCard(boolean identificationCard) {
this.identificationCard = identificationCard;
return this;
}
public Wallet build() {
return new Wallet(this);
}
}
}
자바 빈즈 패턴
빌더 패턴과 달리 생성자로 객체를 생성한 후 Setter Method를 호출하여 매개변수의 값을 설정하는 패턴
설정 해야 할 매개 변수 만큼 Setter 메소드를 호출해며 불변 객체를 생성할 수 없다.
Wallet myWallet = new Wallet();
myWallet.setCash(1000);
myWallet.setIdentificationCard(true);
myWallet.setCreditCard(200);
자바 API Builder 패턴
java.lang.StringBuilder#append() (unsynchronized)
java.lang.StringBuffer#append() (synchronized)
java.nio.ByteBuffer#put() (also on CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer and DoubleBuffer)
javax.swing.GroupLayout.Group#addComponent()
All implementations of java.lang.Appendable
java.util.stream.Stream.Builder
최근엔 롬복의 @Builder 어노테이션으로 인해 코드를 추가적으로 작성해야 하는 경우가 줄어들었다.
하지만 Builder를 커스터마이징 하거나 직접 작성할 때 코드가 장황해지는 단점이 있다.
매개변수가 적은 경우 생성자가 더 가독성이 좋기 때문에 Builder를 무조건 쓰지 않을때도 많았다.
그럼에도 불구하고 매개변수가 많은 객체를 생성할 때 굉장히 좋은 패턴
참고
https://devfunny.tistory.com/337
https://velog.io/@ha0kim/Design-Pattern-생성-패턴Creational-Patterns
https://ko.wikipedia.org/wiki/디자인_패턴_(책)
https://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries/2707195#2707195
https://ko.wikipedia.org/wiki/디자인_패턴_(책) https://velog.io/@ha0kim/Design-Pattern-생성-패턴Creational-Patterns
반응형
'Clean Code' 카테고리의 다른 글
[Design Pattern] 구조 패턴 - 데코레이터 패턴 (0) | 2022.03.03 |
---|---|
[Design Pattern] 생성 패턴 - 싱글톤 패턴 (0) | 2022.03.03 |
[Design Pattern] 생성 패턴 - 프로토 타입 패턴 (0) | 2022.03.03 |
[Design Pattern] 생성 패턴 - 팩토리 메소드 패턴, 추상 팩토리 패턴 (0) | 2022.03.01 |
[Architecture] 아키텍처 개념 정리 (0) | 2022.02.23 |