STUDY/JAVA

[Effective Java] Item 02 μƒμ„±μžμ— λ§€κ°œλ³€μˆ˜κ°€ λ§Žλ‹€λ©΄ λΉŒλ”λ₯Ό κ³ λ €ν•˜λΌ

ozllzL 2023. 9. 25. 23:56

정적 νŒ¨ν„°λ¦¬μ™€ μƒμ„±μžλŠ” λ˜‘κ°™μ€ μ œμ•½μ΄ μžˆλ‹€.

“선택적 λ§€κ°œλ³€μˆ˜κ°€ λ§Žμ„ λ•Œ 적절히 λŒ€μ‘ν•˜κΈ° μ–΄λ ΅λ‹€”

class Book{
    private String title;
    private String publisher;

    private String author;
    private String translator;
	private String painter;

    public Book(String title, String publisher, String author, String translator, String painter){
        this.title = title;
        this.publisher = publisher;
        this.author = author;
        this.translator = translator;
        this.painter = painter;
    }

    public Book(String title, String author, String translator, String publisher){
        this(title, author, translator, null, publisher);
    }

    public Book(String title, String author, String publisher){
        this(title, author, null, null, publisher);
    }

    public Book(String title, String publisher){
        this(title, "미상", null, null, publisher);
    }
}

μœ„ κ²½μš°μ—μ„œλŠ” author, translatorλŠ” 선택적 λ§€κ°œλ³€μˆ˜μ΄λ‹€.

Book book = new ("λˆ„κ°€ λ‚΄ 머리에 λ˜₯μŒŒμ–΄?", "μ‚¬κ³„μ ˆ", "λ² λ₯΄λ„ˆ 홀츠바λ₯΄νŠΈ", null, "λ³Όν”„ 예λ₯ΌλΈŒλ£¨ν");

뭐가 μž‘κ°€κ³  κ·Έλ¦Όμž‘κ°€κ³  null인 것은 무엇인지 μ•Œ μˆ˜κ°€ μ—†λ‹€. κ°œμˆ˜λ„ λͺ‡ κ°œμΈμ§€ μ•ŒκΈ° μ–΄λ ΅λ‹€.

λ§€κ°œλ³€μˆ˜μ˜ κ°œμˆ˜κ°€ 더 λ§Žμ•„μ§€λ©΄ ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ±°λ‚˜ 읽기 μ–΄λ ΅λ‹€.

이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•œ 방법

  • μžλ°” 빈즈 νŒ¨ν„΄
class Book{
    private String title;
    private String publisher;

    private String author;
    private String translator;
    private String painter;

    public void setTitle(String title){this.title = title;}
    public void setPublisher(String publisher){this.publisher = publisher;}
    public void setAuthor(String author){this.author = author;}
    public void setTranslator(String translator){this.translator= translator;}
    public void setPainter(String painter){this.painter= painter;}
}

μž₯점 : μ•žμ—μ„œμ˜ λ¬Έμ œλŠ” 더 이상 보이지 μ•ŠμŒ

단점 : 객체가 μ™„μ „νžˆ μƒμ„±λ˜κΈ° μ „κΉŒμ§„ 일관성이 λ¬΄λ„ˆμ§„ μƒνƒœμ— 놓인닀.

Book book = new Book();
book.setTitle("λˆ„κ°€ λ‚΄ 머리에 λ˜₯ μŒŒμ–΄?");
book.setPublisher("μ‚¬κ³„μ ˆ");

/*μ—¬κΈ°κΉŒμ§€λ§Œ μ‹€ν–‰λœ μƒνƒœλŠ” 일관성이 κΉ¨μ§„ μƒνƒœμ΄λ‹€.*/

book.setAuthor("λ² λ₯΄λ„ˆ 홀츠바λ₯΄νŠΈ");
book.setPainter("λ³Όν”„ 예λ₯ΌλΈŒλ£¨ν");

 

  • λΉŒλ” νŒ¨ν„΄

점측적 μƒμ„±μž νŒ¨ν„΄μ˜ μ•ˆμ „μ„±κ³Ό μžλ°” 빈즈 λ°°ν„΄μ˜ 가독성 κ²ΈλΉ„

class Book{
    private final String title;
    private final String publisher;

    private final String author;
    private final String translator;
    private final String painter;
		
    public static class Builder{
        private final String title;
        private final String publisher;

        private String author;
        private String translator;
        private String painter;

        public Builder(String title, String publisher){
            this.title = title;
            this.publisher = publisher;
        }	

        public Builder author(String author){
            this.author= author;  return this;
        }
        public Builder translator(String translator){
            this.translator= translator;  return this;
        }
        public Builder painter(String painter){
            this.painter= painter;  return this;
        }

        public Book build(){
            return new Book(this);
        }
    } 

    public Book(Builder builder){
        title = builder.title;
        publisher = builder.publisher;
        author = builder.author;
        translator = builder.translator;
        painter = builder.painter;
    }
}
Book book = new Book("λˆ„κ°€ λ‚΄ 머리에 λ˜₯ μŒŒμ–΄?", "μ‚¬κ³„μ ˆ")
		.author("λ² λ₯΄λ„ˆ 홀츠바λ₯΄νŠΈ")
		.painter("λ³Όν”„ 예λ₯ΌλΈŒλ£¨ν").build();

Book book = new ("λˆ„κ°€ λ‚΄ 머리에 λ˜₯μŒŒμ–΄?", "μ‚¬κ³„μ ˆ", "λ² λ₯΄λ„ˆ 홀츠바λ₯΄νŠΈ", null, "λ³Όν”„ 예λ₯ΌλΈŒλ£¨ν");

λͺ¨μ–‘ λ•Œλ¬Έμ— fluent API or method chaining 이라고도 ν•œλ‹€.

잘λͺ»λœ λ§€κ°œλ³€μˆ˜ 감지(λΆˆλ³€μ‹ : ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λŠ” λ™μ•ˆ λ°˜λ“œμ‹œ λ§Œμ‘±ν•΄μ•Όν•˜λŠ” κ·œμΉ™)λ₯Ό μœ„ν•΄ ν•„λ“œ 검사 μ½”λ“œλ„ μΆ”κ°€ν•˜λ©΄ μ’‹λ‹€.

λΉŒλ” νŒ¨ν„΄μ€ 특히 κ³„μΈ΅μ μœΌλ‘œ μ„€κ³„λœ ν΄λž˜μŠ€μ™€ μ“°κΈ° μ’‹μŒ

 

public abstract class Book{
    private final String title;
    private final String publisher;
    final Set<String> authors;

    abstract static class Builder<T extends Builder<T>>{

        private final String title;
        private final String publisher;
        Set<String> authors = Set.noneOf(String.class);

        public T addAuthors(String author){
            authors.add(Objects.requireNonNull(author));
            return self();
        }

	public Builder(String title, String publisher){
            this.title = title;
            this.publisher = publisher;
        }

        abstract Book build();

        protected abstract T self();

    }
    Book(Builder<?> builder){
        title = builder.title;
        publisher = builder.publisher;
        authors = builder.authors.clone();
    }
}

λͺ¨μ–‘ λ•Œλ¬Έμ— fluent API or method chaining 이라고도 ν•œλ‹€.λΉŒλ” νŒ¨ν„΄μ€ 특히 κ³„μΈ΅μ μœΌλ‘œ μ„€κ³„λœ ν΄λž˜μŠ€μ™€ μ“°κΈ° μ’‹μŒ

public class PictureBook extends Book{
    private final String painter;

    public static class Builder extends Book.Builder<Builder>{
        private final String painter;
        public Builder(String title, String publisher, String painter){
            super(title, publisher);
            this.painter = painter;
        }

        @Override public PictureBook build(){
            return new PictureBook(this);
        }

        @Override protected Builder self() {return this; }
    }

    private PictureBook(Builder builder){
        super(builder);
        painter = builder.painter;
    }
}
PictureBook book = new PictureBook.Builder("제λͺ©", "μΆœνŒμ‚¬", "κ·Έλ¦Όμž‘κ°€")
            .addAuthors("μž‘κ°€1").addAuthors("μž‘κ°€2").addAuthors("μž‘κ°€3").build();

ν΄λΌμ΄μ–ΈνŠΈλŠ” ν˜• λ³€ν™˜μ— μ‹ κ²½μ“°μ§€ μ•Šκ³ λ„ λΉŒλ”λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. 아이디, 일련번호 같은 것을 μ•Œμ•„μ„œ μ±„μš°λ„λ‘ ν•  μˆ˜λ„ μžˆλ‹€.

μž₯점 : μœ„ μž₯점 + λΉŒλ” ν•˜λ‚˜λ‘œ μ—¬λŸ¬ 객체λ₯Ό μˆœνšŒν• μˆ˜λ„, λ§€κ°œλ³€μˆ˜μ— 따라 λ‹€λ₯Έ 객체λ₯Ό λ§Œλ“€ μˆ˜λ„ μžˆλ‹€.

단점 : λΉŒλ”λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•˜λŠ”λ° μ„±λŠ₯에 λ―Όκ°ν•œ μƒν™©μ—μ„œλŠ” λ¬Έμ œκ°€ 될 수 μžˆλ‹€.