방법 1 증분 생성자 패턴
public class Member {
private String name; // 필수
private int age; // 필수
private String address; // 선택
private String phone; // 선택
private String email; // 선택
// 필수 매개변수를 가지는 생성자
public Member(String name, int age) {
this(name, age, null, null, null);
}
// 선택 매개변수 address가 추가된 생성자
public Member(String name, int age, String address) {
this(name, age, address, null, null);
}
// 선택 매개변수 phone이 추가된 생성자
public Member(String name, int age, String address, String phone) {
this(name, age, address, phone, null);
}
// 모든 매개변수를 가지는 생성자
public Member(String name, int age, String address, String phone, String email) {
this.name = name;
this.age = age;
this.address = address;
this.phone = phone;
this.email = email;
}
}
//참고 : https://wildeveloperetrain.29
변경하기 번거롭고 읽기 어려운 여러 생성자를 선언하는 방법입니다.
방법 2 JavaBeans 패턴
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(String address) {
this.address = address;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setEmail(String email) {
this.email = email;
}
//참고 : https://wildeveloperetrain.29
Member member = new Member();
member.setName("jan");
member.setAge(99);
member.setAddress("KOR");
member.setPhone("01012345678");
//참고 : https://wildeveloperetrain.29
개체가 완전히 설정되기 전에 일관성그것은 무너진다
불변으로 만들 수 없습니다.
방법 3 빌더 패턴
위의 두 가지 방법을 결합하여 장점만 있는 패턴
필수 매개변수는 생성자를 통해 입력됩니다.
→ 생성자 사용의 이점
추가 매개변수는 JavaBeans 패턴(set 메소드 사용)을 사용하여 입력됩니다.
→ 자바빈즈의 장점
set 메서드의 반환 유형을 빌더 자체로 설정합니다.
fluent API
, 메서드 연쇄
이렇게 구현
빌더 심화(계층적 클래스 및 빌더)
이해가 안되면 출처 링크로 이동하거나 책을 읽으십시오.
import java.util.*;
public abstract class Pizza{
public enum Topping { HAM, MUSHROOM, ONION, PEPPER, SAUSAGE }
final Set<Topping> toppings;
abstract static class Builder<T extends Builder<T>> {
EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
// 하위 클래스 에서 공통으로 사용할 토핑
public T addTopping(Topping topping) {
toppings.add(Objects.requireNonNull(topping));
return self();
}
// Pizza 를 상속받은 클래스 ( NyPizza , Calzone ) return
// 메서드를 구현할 때 NyPizza 와 Calzome의 생성자를 호출하게 된다.
// new NyPizza(this) , new Calzone(this);
abstract Pizza build();
// 하위 클래스는 이 메서드를 재정의하고 this를 반환하도록 해야 한다.
protected abstract T self();
}
// 저장된 토핑이 build()를 호출할 때 각각 생성자에서 super(builer)를 호출하고
// super는 Pizza의 생성자 이므로 아래의 Pizza가 호출 되면서 토핑을 clone()해서
// 저장한다.
Pizza(Builder<?> builder) {
toppings = builder.toppings.clone();
}
// 실제 토핑값을 찍어보기 위한 toString() 재정의
@Override
public String toString() {
Iterator iterator = toppings.iterator();
String returnStr = "";
while(iterator.hasNext()) {
returnStr += iterator.next() + ", ";
}
return returnStr;
}
}
import java.util.Objects;
public class NyPizza extends Pizza {
public enum Size { SMALL, MEDIUM, LARGE }
private final Size size;
public static class Builder extends Pizza.Builder<Builder> {
private final Size size;
// NyPizza 는 size를 받는 생성자만 존재함.
public Builder(Size size) {
super();
this.size = Objects.requireNonNull(size);
}
@Override public NyPizza build() {
return new NyPizza(this);
}
@Override protected Builder self() { return this; }
}
private NyPizza(Builder builder) {
super(builder);
size = builder.size;
}
}
출처: 효과적인 자바
출처 : https://debaeloper.35 (이해가 안되면 이해가 안됨 : 티스토리) See More