JAVA/Effective Java

객체의 생성과 삭제 - 규칙 2 생성자 인자가 많을 때는 Builder 패턴 적용을 고려하라

반응형

기존의 생성자로 많은 인자를 넣어 생성자를 추가하려고 
하는 경우에는 다음과 같이 점층적 생성자 패턴 자주 사용한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
점층적 생성자 패턴
public class Wedul {
    private String teamName;
    private String teamReader;
    private int memberCnt;
    
    public Wedul(String teamName) {
        this(teamName, ""0);
    }
    
    public Wedul(String teamName, String teamReader) {
        this(teamName, teamReader, 0);
    }
    
    public Wedul(String teamName, String teamReader, int memberCnt) {
        this.teamName = teamName;
        this.teamReader = teamReader;
        this.memberCnt = memberCnt;
    }
}
cs




이렇게 다양한 생성자를 만들어야 하며일부 생성자를 만들기 위해서 필요없는 인자값도 넘겨야 하는 상황이 초래된다.
 
그렇기에 코드작성도 어려워지고무엇보다 읽기 어려운 코드가 완성된다.
 
 다른 방법으로 자바빈(JavaBeans) 패턴이 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
자바빈 패턴
public class Wedul {
    private String teamName;
    private String teamReader;
    private int memberCnt;
 
    public Wedul() {}
    
    public void setTeamName(String teamName) {
        this.teamName = teamName;
    }
 
    public void setTeamReader(String teamReader) {
        this.teamReader = teamReader;
    }
 
    public void setMemberCnt(int memberCnt) {
        this.memberCnt = memberCnt;
    }
}
 
// 빈 객체를 먼저 생성하고 그 다음 setter 메서드를 호출하여 필수 필드 뿐만 아니라 선택적 필드의 값을 채울 때 사용.
 
Wedul weduo = new Wedul();
weduo.setTeamName('web');
weduo.setTeamReader('kim');
..
cs




다만 이렇게   한번에 과정으로 객체 생성이 쉽지 않고나중에 요소의 성질이 변할 경우나 
실수로 기입을 하지 못하였을 경우 객체의 일관성이 깨질  있는 문제가 발생된다.
 
그리고 set 같은 설정 메서드가 필히 있어야 하기에 immutable 클래스를 만들  없다.
 
 
이러한 문제들을 토대로
 
만들어진  다른 대책이 builder pattern 이다.



빌더 패턴 (builder pattern)
 
빌더 객체 생성 순서
1. 필수 항목을 생성자에 전부 전달하여 빌더 객체를 만든다.
2. 빌더 객체의 설정 메서드를 호출하여 선택적 항목들에 대한 값을 추가한다.
3. 모든 항목 설정이 완료되면 build() 호출하여 객체를 생성한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Wedul {
    private String teamName;
    private String teamReader;
    private int memberCnt;
    
    public static class Builder {
        // 필수 항목
        private String teamName;
        private int memberCnt;
        
        // 선택적 항목
        private String teamReader = "";
        
        public Builder(String teamName, int memberCnt) {
            this.teamName = teamName;
            this.memberCnt = memberCnt;
        }
        
        public Builder teamReader(String teamReader) {
            this.teamReader = teamReader;
            return this;
        }
        
        public Wedul build() {
            return new Wedul(this);
        }
    }
    
    private Wedul(Builder builder) {
        this.teamName = builder.teamName;
        this.teamReader = builder.teamReader;
        this.memberCnt = builder.memberCnt;
    }
}
 
 
public static void main(String args[]) {
    Wedul wedul = new Wedul.Builder("web"6).teamReader("kim").build();
}
 
cs




 
필더 패턴은 작성해야 하는 코드 양이 많기 때문에,
일반적으로 점층적 생성자 패턴과 정적 팩토리 메서드 패턴을 사용하도록 하고 선택적인 항목이 많은 클래스에 생성자를 생성해야 하는 경우에 빌더 패턴을 하용하는 것이 좋다.




출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙2 인용.



반응형