μμ±μμ μ μ ν©ν 리λ μ νμ λ§€κ°λ³μκ° λ§μ λ μ μ ν λμνκΈ° μ΄λ ΅λ€. μ νμ λ§€κ° λ³μκ° λ§μ κ²½μ°μ μ¬μ©νλ μμ±μ ν¨ν΄μ λν΄μ μ΄ν΄ λ³Ό κ²μ΄λ€.
μμ±μ ν¨ν΄ 1. μ μΈ΅μ μμ±μ ν¨ν΄
μ μΈ΅μ μμ±μ ν¨ν΄(telescoping constructor pattern)μ λ€μκ³Ό κ°μ΄ νμ μΈμλ₯Ό λ°λ μμ±μλ₯Ό μ μν ν, μ νμ μΈμλ₯Ό νλμ© μΆκ°ν΄κ°λ©° μ μνλ κ²μ΄λ€.
Copy public class Item {
private final String itemCd; // νμ
private final String itemNm; // νμ
private final String ctgId; // νμ
private final BigDecimal price; // μ ν
private final String sellTypeCd; // μ ν
public Item(String itemCd, String itemNm, String ctgId){
this(itemCd, itemNm, ctgId, 0);
}
public Item(String itemCd, String itemNm, String ctgId, BigDecimal price){
this(itemCd, itemNm, ctgId, price, "10");
}
public Item(String itemCd, String itemNm, String ctgId, BigDecimal price, String sellTypeCd){
this.itemCd = itemCd;
this.itemNm = itemNm;
this.ctgId = ctgId;
this.price = price;
this.sellTypeCd = sellTypeCd;
}
}
μμμμλ μΈμκ° 5κ°λΌ κ°λ¨ν΄ λ³΄μΌ μ μμ§λ§, λ§€κ°λ³μκ° λ λμ΄λ μλ‘ μ½λλ₯Ό μμ±νκΈ° μ΄λ €μμ§κ³ , κ°λ
μ±μ΄ λ¨μ΄μ§κ² λλ€ .
μμ±μ ν¨ν΄ 2. JavaBeans Pattern
μλ°λΉμ¦ ν¨ν΄μ λ§€κ°λ³μκ° μλ μμ±μλ‘ κ°μ²΄λ₯Ό λ§λ ν setter λ©μλλ₯Ό νΈμΆν΄ μνλ λ§€κ°λ³μμ κ°μ μ€μ νλ λ°©μμ΄λ€.
Copy public class Item {
private String itemCd; // νμ
private String itemNm; // νμ
private String ctgId; // νμ
private BigDecimal price; // μ ν
private String sellTypeCd; // μ ν
public Item() {}
public void setItemCd(String itemCd){ this.itemCd = itemCd; }
public void setItemNm(String itemNm){ this.itemNm = itemNm; }
public void setCtgId(String ctgId){ this.ctgId = ctgId; }
public void setPrice(BigDecimal price){ this.price = price; }
public void setSellTypeCd(String sellTypeCd){ this.sellTypeCd = sellTypeCd; }
}
Copy Item item = new Item();
item.setItemCd("12345678");
item.setItemNm("Effective Java 3/E");
item.setCtgId("9999");
item.setPrice("36000");
item.setSellTypeCd("20");
μλ°λΉμ¦ ν¨ν΄μ μ μΈ΅μ μμ±μ ν¨ν΄μ λ¨μ μ 보μν΄ μΈμ€ν΄μ€ μμ±μ΄ μ½κ³ , λ κ°λ
μ±μ΄ μ’μμ‘λ€.
μμ±μ ν¨ν΄ 3. Builder Pattern
λΉλ ν¨ν΄μ μ μΈ΅μ μμ±μ ν¨ν΄μ μμ μ±κ³Ό μλ°λΉμ¦ ν¨ν΄μ κ°λ
μ±μ κ²ΈλΉν μμ±μ ν¨ν΄μ΄λ€.
Copy public class Item {
private final String itemCd; // νμ
private final String itemNm; // νμ
private final String ctgId; // νμ
private final BigDecimal price; // μ ν
private final String sellTypeCd; // μ ν
public static class Builder {
private final String itemCd; // νμ
private final String itemNm; // νμ
private final String ctgId; // νμ
// μ νμ λ§€κ°λ³μλ default κ°μΌλ‘ μ΄κΈ°ν
private BigDecimal price = BigDecimal.ZERO;
private String sellTypeCd = "00";
public Builder(String itemCd, String itemNm, String ctgId) {
this.itemCd = itemCd;
this.itemNm = itemNm;
this.ctgId = ctgId;
}
public Builder price(BigDecimal price) {
this.price = price;
return this;
}
public Builder sellTypeCd(String sellTypeCd) {
this.sellTypeCd = sellTypeCd;
return this;
}
public Item build() {
return new Item(this);
}
}
private Item(Builder builder) {
itemCd = builder.itemCd;
itemNm = builder.itemNm;
ctgId = builder.ctgId;
price = builder.price;
sellTypeCd = builder.sellTypeCd;
}
}
Copy Item item = new Item.Builder("12345678", "Effective Java 3/E", "9999").price(36000).sellTypeCd("90").build();
ν΄λΌμ΄μΈνΈλ νμ λ§€κ°λ³μλ§μΌλ‘ μμ±μλ₯Ό νΈμΆν΄ λΉλ κ°μ²΄λ₯Ό μ»κ³ , λΉλ κ°μ²΄κ° μ 곡νλ setter λ©μλλ€λ‘ μνλ μ ν λ§€κ°λ³μλ€μ μ€μ ν μ μλ€. λ§μ§λ§μΌλ‘ λ§€κ°λ³μκ° μλ build()
λ©μλλ₯Ό νΈμΆν΄ νμν κ°μ²΄λ₯Ό μ»μ μ μλ€. μ΄λ κ² μ°μμ μΌλ‘ λ©μλλ₯Ό νΈμΆνλ λ°©λ²μ fluent API or method chaining μ΄λΌ νλ€.
λΆλ³ : μ΄λ ν λ³κ²½λ νμ©νμ§ μλλ€. λνμ μΌλ‘ String κ°μ²΄λ νλ² λ§λ€μ΄μ§λ©΄ μ λ κ°μ λ°κΏ μ μλ λΆλ³ κ°μ²΄
λΆλ³μ : νλ‘κ·Έλ¨μ΄ μ€νλλ λμ(νΉμ μ ν΄μ§ κΈ°κ°) λ°λμ λ§μ‘±ν΄μΌνλ 쑰건μ λ§νλ€. λ³κ²½μ νμ©ν μ λ μμΌλ, μ£Όμ΄μ§ 쑰건 λ΄μμλ§ νμ©νλ€λ λ»μ΄λ€.
κ³μΈ΅μ μΌλ‘ μ€κ³λ ν΄λμ€
λΉλ ν¨ν΄μ κ³μΈ΅μ μΌλ‘ μ€κ³λ ν΄λμ€μ μ¬μ©νκΈ°μ μ’λ€.
Copy public abstract class Allnco {
public enum ApiType { ADD_ITEM, UPDATE_ITEM, UPDATE_IMAGE, UPDATE_PRC }
final Set<ApiType> apiTypes;
abstract static class Builder<T extends Builder<T>> {
EnumSet<ApiType> apiTypes = EnumSet.noneOf(ApiType.class);
public T addApiType(ApiType apiType){
apiTypes.add(Objects.requireNonNull(apiType));
return self();
}
abstract Allnco build();
// νμ ν΄λμ€λ μ΄ λ©μλλ₯Ό overridingν΄ "this"λ₯Ό λ°ννλλ‘ κ΅¬νν΄μΌν¨.
protected abstract T self();
}
Allnco(Builder<?> builder){
apiTypes = builder.apiTypes.clone();
}
}
Copy public class Gmarket extends Allnco{
public enum Chnl { ONLINE, OUTLET, MART, DEPARTMENT, BUYING }
private final Chnl chnl; // final -> immutable
public static class Builder extends Allnco.Builder<Builder> {
private final Chnl chnl;
public Builder(Chnl chnl){
this.chnl = Objects.requireNonNull(chnl);
}
@Override
public Gmarket build(){
return new Gmarket(this);
}
@Override
protected Builder self(){
return this;
}
}
private Gmarket(Builder builder){
super(builder);
chnl = builder.chnl;
}
}
Copy public class Naver extends Allnco{
private final boolean isHapi;
public static class Builder extends Allnco.Builder<Builder> {
public boolean isHapi = false;
public Builder connectToHapi(){
isHapi = true;
return this;
}
@Override
public Naver build(){
return new Naver(this);
}
@Override
protected Builder self(){
return this;
}
}
private Naver(Builder builder){
super(builder);
isHapi = builder.isHapi;
}
}
Copy Gmarket gmarket = new Gmarket.Builder(Gmarket.Chnl.MART).addApiType(Gmarket.ApiType.UPDATE_ITEM).addApiType(Gmarket.ApiType.UPDATE_PRC).build();
Naver naver = new Naver.Builder().addApiType(Naver.ApiType.ADD_ITEM).connectToHapi().build();
κ°κ°μ νμ ν΄λμ€μ λΉλκ° μ μν build
λ©μλλ ν΄λΉ νμ ν΄λμ€(Naver
, Gmarket
)μ λ°ννλλ‘ λμ΄μλ€. μ΄λ κ² νμ ν΄λμ€μ λ©μλκ° μμ ν΄λμ€κ° μ μν λ¦¬ν΄ νμ
μ΄ μλ, κ·Έ νμ νμ
μ 리ν΄νλ κ²μ Convariant return typing (κ³΅λ³ λ°ν νμ΄ν)μ΄λΌ νλ€. μ΄ κΈ°λ₯μΌλ‘ ν΄λΌμ΄μΈνΈκ° νλ³νμ μ κ²½ μ°μ§ μκ³ λΉλλ₯Ό μ¬μ©ν μ μλ€.
κ²°λ‘
λΉλ ν¨ν΄μ λΉλ νλλ‘ μ¬λ¬ κ°μ²΄λ₯Ό λ§λ€ μ μκ³ , λΉλμ λκΈ°λ λ§€κ°λ³μμ λ°λΌ λ€λ₯Έ κ°μ²΄λ₯Ό λ§λ€ μ μμΌλ―λ‘ λ§€μ° μ μ° νλ€.
νμ§λ§ κ°μ²΄λ₯Ό λ§λ€λ €λ©΄, κ·Έμ μμ λΉλλΆν° λ§λ€μ΄μΌνλ€. λν, μ±λ₯μ λ―Όκ°ν μν©μμλ λΉλ μμ± λΉμ©μ΄ λ¬Έμ κ° λ μ μλ€. λν λ§€κ°λ³μκ° 4κ° μ΄μμ΄ λμ΄μΌ κ°μ΄μΉλ₯Ό νλ€.
μ¦, μΈμκ° λ§μ μμ±μ λ μ μ ν©ν°λ¦¬κ° νμν ν΄λμ€λ₯Ό μ€κ³ ν λ, λλΆλΆμ μΈμκ° μ νμ μΈμ μΈ μν©μ μ μ©νλ€. λΉλλ μ μΈ΅μ μμ±μλ³΄λ€ κ°κ²°νκ³ , μλ°λΉμ¦λ³΄λ€ ν¨μ¬ μμ νλ€.