ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] 빌더 패턴 (Builder Pattern)
    공부/디자인 패턴 2020. 2. 22. 23:25

    Builder 패턴이란?

    빌더 패턴은 객체를 빌드하는데 사용됩니다. 생성하는 객체가 하위 객체들을 포함하고 있어 복잡하거나 구성을 정교하게 할 필요성이 있을 때, 빌더 패턴을 사용해 복잡한 유형을 단순화할 수 있습니다. 빌더 패턴은 복잡한 객체를 빌드하는 프로세스를 캡슐화 또는 숨기는 작업을 하고 객체와 해당 구조의 표현을 분리합니다.


    그냥 간단하게 말해서 생성자를 통해 어떠한 값도 생성하지 않고 내부 클래스 (보통 빌더라고 이름을 지음)를 통하여 생성하도록 하는 패턴입니다.

    예시

    class Student {
        private Student(int number, String name) {
        }
    
        public static class Builder {
            int number=0;
            String name=null;
    
            public Builder() {
            }
    
            public Builder setNumber(int number) {
                this.number = number;
                return this;
            }
    
            public Builder setName(String name) {
                this.name = name;
                return this;
            }
    
            public Student build() {
                return new Student(number, name);
            }
        }
    }
    
    
    // 호출 
    public void Temp() {
        Student student = new Student.Builder().setNumber(number).setName(name).build();
    }

    나무위키 예시: https://namu.wiki/w/%EB%94%94%EC%9E%90%EC%9D%B8%20%ED%8C%A8%ED%84%B4#s-3.3

    사용 목적

    빌더 패턴을 사용하는 목적은 두 가지로 확인할 수 있습니다.

    결합도 분리

    위의 Student 클래스의 요구사항이 추가되어 생성자에 파라미터로 전달해야 하는 부분이 변경되면 골치가 아파집니다. 예를 들어, 빌더 패턴을 사용하지 않은 경우에는 Student(10, "홍길동")이 들어가는데 숫자와 이름 사이에 핸드폰 번호라는 값이 들어간다면 Student 클래스의 생성자는 물론, 해당 클래스를 사용하는 모든 내용을 찾아 변경해줘야 합니다.

    이러한 문제를 빌더 패턴을 사용하면 손쉽게 해결할 수 있습니다. Student 클래스의 생성자에 핸드폰 번호를 추가하고 Builder 부분에 핸드폰 번호를 받는 setCellphone(String cellphone)을 추가하면 됩니다.

    생성자에 전달하는 인수에 의미 부여

    위의 Student 클래스를 빌더 패턴이 아닌 보통의 방법으로 인스턴스화 할 때, new Student(10, "홍길동"); 과 같이 작성합니다. 하지만 파라미터가 많아지면 해당 클래스에 어떤 파라미터가 넘어가는지 자리의 순서를 외워야 하고 해당 코드만 봤을 때, 입력된 파라미터의 자리에 어떤 변수를 할당하는지 알 수 없습니다. 

    빌더 패턴을 사용하면 set파라미터명 과 같은 형식으로 전달하기 때문에 어떤 파라미터에 값을 넣는지 명확해 집니다.

    파이썬에서..

    사실상 위 빌더 패턴은 파이썬에서는 크게 의미가 있는 디자인 패턴은 아니라고 생각합니다.

    파이썬에서는 키워드 인자라는 기능이 존재해서 클래스의 인스턴스를 생성할 때, 어떤 파라미터에 값을 넣는지 강제로 명시를 할 수 있습니다(2번 해결). 또한, 키워드 인자로 넘겨주면 파라미터의 순서는 상관이 없습니다(1번 해결).

    class Student:
        def __init__(self, *, number, name):
            self.__number = number
            self.__name = name
    
        @property
        def number(self):
            return self.__number
    
        @property
        def name(self):
            return self.__name
    
    
    Student(10, '홍길동') # 오류발생
    student = Student(name='홍길동', number=10)
    
    # 오류
    student.number = 20


    댓글