반응형

안녕하세요 취업길잡이 Coy입니다

오늘은 빌더 패턴(Builer Pattern)에 대해서 알아보도록 하겠습니다

 

빌더 패턴이란

빌더 패턴은 복잡한 객체의 생성 과정과 표현 방법을 분리하여 객체를 다양한 방식으로 생성하는 디자인 패턴입니다. 객체 생성을 일련의 단계로 나누고, 빌더 클래스를 사용하여 필수적인 속성을 설정하고 선택적으로 다양한 속성을 추가할 수 있습니다.

예를 들어, 자동차 빌더에서는 차체, 엔진, 내부 장식 등을 설정하고, 필요한 옵션만 선택하여 다양한 자동차 인스턴스를 생성할 수 있습니다. 이는 자동차의 다양한 종류에 대한 유연성을 제공합니다.

이런식으로 빌더 패턴은 객체 생성의 복잡성과 다양성을 다루는 데 유용하며, 객체의 생성 과정과 표현 방법을 추상화하여 유연성을 확보합니다.

사용하는 목적

  1. 일관성 문제 해결: 빌더 패턴은 필수 매개변수를 강제하며, 객체 생성 시 필요한 값들을 빠뜨리는 일관성 문제를 해결합니다. 클라이언트는 빌더 클래스를 통해 필수 값들을 설정하고 누락된 값이 없도록 보장할 수 있습니다.
  2. 불변성 보장: 자바 빈즈 패턴에서는 Setter 메서드를 노출하여 객체를 외부에서 변경할 수 있지만, 빌더 패턴에서는 최종적으로 build() 메서드를 호출하여 불변한 객체를 생성합니다. 이로써 외부에서 객체를 불변하게 유지할 수 있어, 객체의 일관성과 안정성을 보장합니다.
  3. 가독성 향상: 빌더 패턴은 체이닝 형태로 메서드를 호출하므로, 객체를 생성하면서 필요한 값을 명시적으로 표현할 수 있습니다. 이는 가독성을 향상시키며, 어떤 값이 어떤 의미를 가지는지 쉽게 이해할 수 있도록 합니다.
  4. 변경 용이성: 빌더 패턴은 객체 생성에 필요한 각각의 단계를 메서드로 분리하여 구현하므로, 단일 단계의 변경이 전체 시스템에 미치는 영향을 최소화할 수 있습니다. 새로운 단계를 추가하거나 기존 단계를 수정하더라도 해당 부분만 수정하면 되므로 유지보수가 용이합니다.
  5. 선택적 파라미터 관리 용이성: 생성자 오버로딩에서 발생하는 선택적 파라미터의 순서나 누락 문제를 해결합니다. 빌더 패턴을 사용하면 클라이언트는 필요한 값을 명시적으로 지정할 수 있으며, 순서에 구애받지 않아도 됩니다. 이는 유연성을 높이고 실수를 방지하는 데 도움이 됩니다.

구조

 

예제 코드

class Product {
    private String part1;
    private int part2;
    private boolean part3;

    // 생성자, getter 메서드 등...

    @Override
    public String toString() {
        return "Product{" +
                "part1='" + part1 + '\'' +
                ", part2=" + part2 +
                ", part3=" + part3 +
                '}';
    }
}
interface Builder {
    void buildPart1();
    void buildPart2();
    void buildPart3();
    Product getResult();
}
class ConcreteBuilder1 implements Builder {
    private Product product = new Product();

    @Override
    public void buildPart1() {
        product.setPart1("Part1 from Builder1");
    }

    @Override
    public void buildPart2() {
        product.setPart2(42);
    }

    @Override
    public void buildPart3() {
        product.setPart3(true);
    }

    @Override
    public Product getResult() {
        return product;
    }
}
// ConcreteBuilder2, ConcreteBuilder3 클래스도 유사하게 구현
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPart1();
        builder.buildPart2();
        builder.buildPart3();
    }
}

public class BuilderPatternExample {
    public static void main(String[] args) {
        // 클라이언트는 ConcreteBuilder를 선택
        Builder builder = new ConcreteBuilder1();

        // 디렉터를 통해 제품 생성
        Director director = new Director(builder);
        director.construct();

        // 완성된 제품 얻기
        Product product = builder.getResult();

        // 결과 출력
        System.out.println(product);
    }
}
  1. Product 클래스:
    • Product 클래스는 최종적으로 생성되는 제품을 나타냅니다.
    • part1, part2, part3로 구성되어 있으며, 빌더 패턴에서 생성될 제품의 일부분들을 담고 있습니다.
  2. Builder 인터페이스:
    • Builder 인터페이스는 제품의 생성 과정을 추상화한 것으로, 구체적인 빌더 클래스들이 이를 구현합니다.
    • buildPart1(), buildPart2(), buildPart3(), getResult() 메서드로 구성되어 있습니다.
  3. ConcreteBuilder1 클래스:
    • ConcreteBuilder1 클래스는 Builder 인터페이스를 구현하여 제품의 일부분들을 생성하는 역할을 합니다.
    • buildPart1()에서는 part1을 설정하고, buildPart2()에서는 part2를 설정하며, buildPart3()에서는 part3를 설정합니다. getResult() 메서드에서는 완성된 Product 객체를 반환합니다.
  4. ConcreteBuilder2, ConcreteBuilder3 클래스:
    • ConcreteBuilder2, ConcreteBuilder3 클래스도 ConcreteBuilder1과 유사하게 Builder 인터페이스를 구현합니다.
    • 각각의 빌더 클래스에서는 자신의 방식대로 part1, part2, part3를 설정하고 결과를 반환합니다.
  5. Director 클래스:
    • Director 클래스는 클라이언트가 어떤 빌더를 선택하든 일관된 인터페이스를 제공하여 제품을 조립합니다.
    • construct() 메서드에서는 빌더의 메서드들을 호출하여 제품을 조립합니다.
  6. 클라이언트 코드 (BuilderPatternExample 클래스):
    • 클라이언트 코드에서는 특정 빌더를 선택하고, 해당 빌더를 이용하여 Director를 통해 제품을 생성합니다.
    • 결과로 완성된 제품을 출력합니다.

빌더 패턴의 장단점

장점

1. 유연성 및 확장성: 빌더 패턴을 사용하면 제품의 각 부분을 담당하는 빌더 클래스를 추가하거나 수정함으로써 다양한 종류의 제품을 생성할 수 있습니다. 새로운 빌더 클래스를 추가하거나 기존 빌더 클래스를 수정함으로써 시스템에 새로운 제품이나 기능을 손쉽게 추가할 수 있습니다.
2. 가독성 및 유지보수성 향상: 복잡한 객체의 생성 코드를 각각의 빌더 클래스로 분리하면 가독성이 향상되고 유지보수가 용이해집니다. 각 빌더 클래스는 특정 부분의 생성에 집중하므로 코드의 일관성이 유지되며, 변경이 필요한 경우 해당 빌더 클래스만 수정하면 됩니다.
3. 필수 및 선택적 매개변수 처리: 빌더 패턴은 객체 생성에 필요한 필수 매개변수와 선택적 매개변수를 구분하여 처리할 수 있습니다. 이로써 가독성이 높아지고 클라이언트는 필요한 부분만 설정하여 원하는 형태의 객체를 생성할 수 있습니다.

 

단점

1. 코드 복잡성: 빌더 패턴을 구현하려면 여러 클래스를 만들어야 하므로 코드의 양이 늘어날 수 있습니다. 작은 규모의 객체나 간단한 객체의 경우에는 빌더 패턴을 사용하는 것이 오히려 더 복잡해질 수 있습니다.
2. 성능 오버헤드: 객체를 생성하는 데 필요한 여러 단계와 객체들 간의 상호작용이 있기 때문에 성능 면에서 다른 생성 패턴에 비해 오버헤드가 발생할 수 있습니다. 하지만 대부분의 경우에는 성능상 큰 문제가 되지 않습니다.
3. 불필요한 객체 생성: 빌더 패턴을 사용하면 중간 단계에서 생성된 객체들이 메모리를 차지하게 될 수 있습니다. 이는 객체가 복잡한 경우에 불필요한 메모리 소비로 이어질 수 있습니다.

 

오늘 이렇게 빌더 패턴에 대해서 알아보았습니다.

디자인 패턴 자체가 가독성을 좋게 하거나, 유지보수가 용이하게 해주는 것은 맞지만, 상황에 따라 잘 사용하는 것이 중요합니다

출처(https://m.yes24.com/Goods/Detail/17525598)


컬럼으로 다루어 주면 좋겠다 싶은 주제가 있으면 댓글로 알려주세요

 

도움이 필요하시면 사연을 메일로 보내주세요

 

jek300300@gmail.com

 

도움이 되셨다면 공감과 구독 부탁드립니다

 

읽어주셔서 감사합니다

 

당신의 취업이 성공할 때까지 같이 하겠습니다! by 취업길잡이 Coy

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기