모르는게 많은 개발자

[디자인 패턴] Builder Pattern 개념/예제 본문

디자인패턴

[디자인 패턴] Builder Pattern 개념/예제

Awdsd 2020. 12. 19. 15:24
반응형

1. 빌더 패턴

빌더 패턴은 객체를 생성할 때 흔하게 사용하는 패턴이다. 아래와 같은 방식으로 객체가 생성되면 Builder Pattern을 활용한 것이다.

Person person = Person.builder()
    .name("a")
    .age(13)
    .build();

빌더 패턴은 흔히 생성자 인자 많을 때 고려된다.

빌더 패턴 구현 예제를 보기전에 객체를 만드는 패턴 두가지를 알아보자.


2. 점층적 생성자 패턴

점층적 생성자 패턴은 내가 사용할 인자를 받는 생성자를 모두 만드는 것이다.

예를 들어 아래 코드처럼 a만 인자로 받는 생성자가 필요할 수도 있고, a, b, c, d를 모두 받는 생성자가 필요한 등 내가 사용할 생성자들을 모두 만들어서 사용하는 패턴이다.

class Person {
    String a;
    String b;
    String c;
    String d;

    public Person(String a) {
        this.a = a;
    }

    public Person(String a, String b, String c, String d) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }
    
    public Person(String a, String c) {
        this.a = a;
        this.c = c;
    }
}

하지만 이 패턴은 인자가 추가되거나 했을 때 코드를 수정하기 어렵고, 인자수가 많을 떄 객체를 생성할 때 인자 하나하나가 어떤 역할인지 바로 알 수 없어 가독성이 떨어지는 단점이 있다.

Ex)
//각 인자가 어떤 의미인지 어려움
Person person = new Person("z", "a", "s", "d");

3. 자바빈 패턴

자바빈 패턴은 setter 메소드를 이용한 패턴이다. 아래처럼 set함수를 사용해 하나하나 값을 넣어준다.

하지만 이 패턴의 경우 무조건 setter함수가 존재해야하므로 변경 불가 클래스를 만들 수 없고, 1회의 호출로 객체 생성이 완료되지 않는다.

public static Person create() {
        Person person = new Person();
        person.setA("a");
        person.setB("b");
        person.setC("c");
        person.setD("d");
        person.setF("f");
        person.setG("g");
        //...
        return person;
    }

4. 빌더 패턴 구현

이제 빌더 패턴을 구현해보자

빌더 패턴은 빌더 클래스를 정의해서 각 인자를 받고나서 반환으로 빌더 객체를 반환하여 체이닝(.a().b().c().d())형식으로 사용할 수 있다.

이 패턴의 장점은 각 인자가 어떤 의미인지 쉽게 알 수 있고, setter를 만들지 않아도 되므로 변경 불가 객체를 만들 수 있다. 또한 build()함수에서 값 검증을 수행할 수 있다.

public class Main {
    public static void main(String[] args) {
        Person person = Person.builder()
                .a("a")
                .b("b")
                .c("c")
                .d("d")
                .build();
        System.out.println(
                person.getA() +
                person.getB() +
                person.getC() + person.getD());
    }
}

class Person {
    private String a;
    private String b;
    private String c;
    private String d;
    //Builder 객체 생성
    public static PersonBuilder builder() {
        return new PersonBuilder();
    }
    //getter...

    static class PersonBuilder {
        String a;
        String b;
        String c;
        String d;

        PersonBuilder a(String a) {
            this.a = a;
            return this;
        }

        PersonBuilder b(String b) {
            this.b = b;
            return this;
        }

        PersonBuilder c(String c) {
            this.c = c;
            return this;
        }

        PersonBuilder d(String d) {
            this.d = d;
            return this;
        }
        //객체 생성 
        Person build() {
            Person person = new Person();
            person.a = this.a;
            person.b = this.b;
            person.c = this.c;
            person.d = this.d;
            return person;
        }
    }
}

 

반응형
Comments