빌더 디자인 패턴과 팩토리 디자인 패턴의 차이점은 무엇입니까?


663

빌더 디자인 패턴과 팩토리 디자인 패턴의 차이점은 무엇입니까?

어느 것이 더 유리하고 왜 그럴까요?

이러한 패턴을 테스트하고 비교 / 대비하려면 결과를 그래프로 어떻게 표현합니까?


13
그들은 다른 일을하기 때문에 "이점"은 무엇을 의미합니까?
S.Lott

5
Builder 는 더 복잡한 버전의 생성자 - 팩토리 메소드 는 단순화 된 것입니다.
Dávid Horváth

@ DávidHorváth 빌더를 "더 복잡한"것으로 설명하지는 않습니다. 100 개의 매개 변수가있는 생성자를 처리하고 그 중 3 개만 신경 쓰면 향후 매개 변수 수가 변경 될 수 있음을 알고 있으면 빌더 패턴을 사용하면 모든 사람의 삶이 훨씬 간단 해집니다.
Aberrant

@Aberrant 복잡한 사용법과 아키텍처의 복잡성은 서로 다른 두 가지입니다. 나는 후자에 집중했다.
Dávid Horváth

답변:


466

디자인 패턴을 사용하면 일반적으로 모든 경우에 적합한 "더 유리한"솔루션이 없습니다. 구현해야 할 내용에 따라 다릅니다.

Wikipedia에서 :

  • Builder는 복잡한 객체를 단계별로 구성하는 데 중점을 둡니다. Abstract Factory는 제품군의 제품군 (간단하거나 복잡한)을 강조합니다. Builder는 제품을 최종 단계로 반환하지만 Abstract Factory에 관한 한 제품은 즉시 반환됩니다.
  • 빌더는 종종 컴포지트를 빌드합니다.
  • 종종 디자인은 Factory Method (더 복잡하지 않고 사용자 정의가 가능하며 서브 클래스가 확산 됨)를 사용하여 시작하여 설계자가 더 많은 유연성이 필요한 곳을 발견함에 따라 Abstract Factory, Prototype 또는 Builder (보다 유연하고 더 복잡한)로 발전합니다.
  • 때로는 생성 패턴이 보완적일 수 있습니다. Builder는 다른 패턴 중 하나를 사용하여 구성 요소를 작성할 수 있습니다. Abstract Factory, Builder 및 Prototype은 구현에서 Singleton을 사용할 수 있습니다.

팩토리 디자인 패턴에 대한 Wikipedia 항목 : http://en.wikipedia.org/wiki/Factory_method_pattern

빌더 디자인 패턴에 대한 Wikipedia 항목 : http://en.wikipedia.org/wiki/Builder_pattern


159
이것이 바로 차이점입니다. 빌더는 한 단계에서 오브젝트를 생성 할 수없는 경우에만 필요합니다. 이것의 좋은 예는 복잡한 객체에 대한 역 직렬화 프로세스에 있습니다. 복잡한 개체의 매개 변수를 하나씩 검색해야하는 경우가 종종 있습니다.
Bernard Igiri

1
첫 번째 문장의 경우, 광범위하게 적용되는 더 유리한 솔루션이 절대적으로 있다고 말할 것입니다 ... 우리는 이것들이 프로그래밍 언어로 직접 구워지기 때문에 이것을 보지 못합니다.
Joel Coehoorn

4
@Joel : 일부 패턴이 다른 패턴보다 일반적이라는 점에 동의하지만 (예 : Factory가 Builder보다 일반적 인 것 같습니다) 시나리오의 모양에 관계없이 항상 다른 패턴보다 나은 패턴은 없다는 것입니다 .
Adrian Grigore

@AdrianGrigore 둘 다 혼합하면 어떻게 될까요 ?? aso.net mvc ControllerFactory 클래스에 대한 메소드를 설정하고 얻는 ControllerBuilder가 있습니다
AminM

추가해야 할 두 가지 사항은 다음과 같습니다. 1) Builder는 주로 Fluent API를 사용하여 POJO를 빌드하는 데 사용됩니다 (예 : Person.builder (). withName ( "Sam"). withAge (38) .build (). 2) 내 experiene에서 builder는 도메인 객체의 POJO 생성에 유용하지만 factory는 PdfGeneratorFactory 클래스와 같은 서비스 객체를 생성하는 데 유용합니다. 서비스 오브젝트는 공장에서 1 회 이상 사용하도록 캐시 될 수있는 반면, 빌더는 설계 상 항상 새 오브젝트를 작성합니다.
saurabh.

359

팩토리 는 단순히 생성자 주위의 래퍼 함수입니다 (아마도 다른 클래스에있는 것). 가장 큰 차이점은 팩토리 메소드 패턴은 전체 매개 변수가 단일 행으로 전달 된 전체 메소드를 단일 메소드 호출로 빌드해야한다는 것입니다. 최종 객체가 반환됩니다.

반면에 빌더 패턴 은 본질적으로 생성자 호출에 전달할 수있는 모든 가능한 매개 변수 주위의 랩퍼 오브젝트입니다. 이를 통해 setter 메소드를 사용하여 매개 변수 목록을 천천히 작성할 수 있습니다. 빌더 클래스의 추가 메소드 중 하나는 build () 메소드입니다. 이는 단순히 빌더 오브젝트를 원하는 생성자로 전달하고 결과를 리턴합니다.

Java와 같은 정적 언어에서는 가능한 모든 매개 변수 조합에 대해 텔레스코픽 생성자를 가질 필요가 없으므로 소수의 (잠재적으로 선택적인) 매개 변수가있는 경우 더 중요합니다. 또한 빌더를 사용하면 생성자 호출 후 직접 수정할 수없는 읽기 전용 또는 개인 필드를 정의하기 위해 setter 메소드를 사용할 수 있습니다.

기본 공장 예

// Factory
static class FruitFactory {
    static Fruit create(name, color, firmness) {
        // Additional logic
        return new Fruit(name, color, firmness);
    }
}

// Usage
Fruit fruit = FruitFactory.create("apple", "red", "crunchy");

기본 빌더 예

// Builder
class FruitBuilder {
    String name, color, firmness;
    FruitBuilder setName(name)         { this.name     = name;     return this; }
    FruitBuilder setColor(color)       { this.color    = color;    return this; }
    FruitBuilder setFirmness(firmness) { this.firmness = firmness; return this; }
    Fruit build() {
        return new Fruit(this); // Pass in the builder
    }
}

// Usage
Fruit fruit = new FruitBuilder()
        .setName("apple")
        .setColor("red")
        .setFirmness("crunchy")
        .build();

이 두 위키 백과 페이지의 코드 샘플을 비교해 볼 가치가 있습니다.

http://en.wikipedia.org/wiki/Factory_method_pattern
http://en.wikipedia.org/wiki/Builder_pattern


1
빌더 패턴 imo의 올바른 사용법은 아닙니다. 위키 링크에서도 사용법을 바꿨습니다. 이 FruitBuilder는 Director와 Builder 구성 요소가 혼합되어 있으며 Director 구성 요소에 속하는 build ()와 Builder 구성 요소에 속하는 setter를 호출합니다. Director는 빌더 메소드를 사용하여 오브젝트를 작성하는 방법에 대한 비즈니스 로직을 포함해야합니다. 유창한 API는 빌더 패턴이 아니며 StringBuilder도 빌더 패턴이 아닙니다.
Kmaczek

282

팩토리 패턴은 대부분 빌더 패턴의 단순화 된 버전으로 볼 수 있습니다.

에서 공장 패턴, 공장은 필요에 따라 개체의 다양한 아형을 만드는 담당하고있다.

팩토리 메소드의 사용자는 해당 오브젝트의 정확한 서브 타입을 알 필요가 없습니다. 팩토리 메소드의 예는 또는 유형이 지정된 오브젝트를 createCar리턴 할 수 있습니다 .FordHonda

에서 빌더 패턴, 다른 아형은 작성기 방법으로 만들지 만, 물체의 조성물은 같은 서브 클래스 내에서 다를 수있다.

자동차 예제를 계속하려면 4 개의 실린더 엔진 createCar으로 Honda유형이 지정된 오브젝트 를 작성 하거나 Honda6 개의 실린더 로 유형 이 지정된 오브젝트 를 작성 하는 빌더 메소드 가있을 수 있습니다 . 빌더 패턴은이 세밀한 세분성을 허용합니다.

빌더 패턴팩토리 메소드 패턴 모두의 다이어그램은 Wikipedia에서 사용 가능합니다.


13
빌더 패턴은 큰 오브젝트의 구성을 확대하는 것과 같습니다. 큰 객체는 재귀와 같이 더 구성된 다른 객체로 구성됩니다. 공장은 한 번의 통화로 물건을 얻을 수 있습니다. 이 이해가 맞습니까?
Fooo

63

빌더 디자인 패턴은 여러 단계에 걸쳐 특정 유형의 다른 오브젝트를 작성하는 방법을 알고있는 오브젝트를 설명합니다. 각 중간 단계에서 대상 항목에 필요한 상태를 유지합니다. StringBuilder가 최종 문자열을 생성하기 위해 어떤 과정을 거쳐야하는지 생각해보십시오.

팩토리 디자인 패턴은 특정 매개 변수를 기반으로 특정 유형이 선택되는 한 단계에서 여러 가지 관련이있는 여러 종류의 오브젝트를 작성하는 방법을 알고있는 오브젝트를 설명합니다. 직렬화 시스템을 작성하고 직렬화기를 작성하면 한 번의 호출로 원하는 오브젝트를 구성 할 수 있습니다.


7
힌트 : 빌더 패턴의 좋은 예는 "유창한 인터페이스"이고 ADO.NET에는 "공장"및 "추상 팩토리"구현 (예 : DbFactory)이 가득합니다.
boj 2009

50
  • 단계별로 복잡한 객체 생성 : 빌더 패턴

  • 단일 메소드를 사용하여 간단한 오브젝트를 작성합니다. 팩토리 메소드 패턴

  • 여러 팩토리 메소드를 사용하여 오브젝트 작성 : 추상 팩토리 패턴


21

빌더 패턴과 팩토리 패턴은 둘 다 개체를 생성하기 때문에 육안과 매우 유사 해 보입니다.

근데 좀 더 가까이 봐야 해

이 실제 예제는 둘 사이의 차이점을 더 명확하게 만듭니다.

가정 당신은 패스트 푸드 레스토랑에 가서 당신이 주문한 음식을 .

1) 무슨 음식?

피자

2) 토핑은 무엇입니까?

고추, 토마토, 바베 큐 치킨, 아니 파인애플

따라서 다양한 종류의 음식은 팩토리 패턴으로 만들어 지지만 특정 음식의 다른 변형 (맛)은 빌더 패턴으로 만들어집니다.

다른 종류의 음식

피자, 버거, 파스타

피자의 변종

치즈, 치즈 + 토마토 + 고추, 치즈 + 토마토 등

코드 샘플

여기서 두 패턴의 샘플 코드 구현을 볼 수 있습니다.
Builder Pattern
Factory Pattern


1
샘플 코드를 제공해 주셔서 감사합니다! 귀하의 예는이 두 패턴을 매우 잘 구분합니다.
Rommel Paras 19

18

둘 다 객체를 만들기위한 창조 패턴입니다.

1) 팩토리 패턴-하나의 수퍼 클래스와 N 개의 서브 클래스가 있다고 가정하십시오. 전달되는 매개 변수 / 값에 따라 오브젝트가 작성됩니다.

2) 빌더 패턴-복잡한 오브젝트를 작성합니다.

Ex: Make a Loan Object. Loan could be house loan, car loan ,
    education loan ..etc. Each loan will have different interest rate, amount ,  
    duration ...etc. Finally a complex object created through step by step process.

12

먼저 내 논쟁을 따라야 할 몇 가지 일반적인 사항 :

큰 소프트웨어 시스템을 설계 할 때 가장 큰 과제는 유연하고 변화가 복잡해야한다는 것입니다. 이러한 이유로 커플 링 및 응집력과 같은 몇 가지 메트릭이 있습니다. 전체 시스템을 처음부터 다시 디자인 할 필요없이 기능을 쉽게 변경하거나 확장 할 수있는 시스템을 구현하려면 설계 원칙 (SOLID 등)을 따를 수 있습니다. 얼마 후 일부 개발자는 이러한 원칙을 따르면 유사한 문제에 잘 맞는 유사한 솔루션이 있음을 인식했습니다. 이러한 표준 솔루션은 디자인 패턴으로 판명되었습니다.

따라서 디자인 패턴은 응집력이 높은 느슨하게 결합 된 시스템을 달성하기 위해 일반적인 디자인 원칙을 따르도록 지원합니다.

질문에 대답하기 :

두 패턴의 차이점을 물어 봄으로써 어떤 패턴이 시스템을 더 유연한 방식으로 만드는지 스스로에게 묻어 야합니다. 각 패턴에는 시스템 클래스 간 종속성을 구성하는 고유 한 목적이 있습니다.

추상 팩토리 패턴 : GoF : "구체적인 클래스를 지정하지 않고 관련 또는 종속 객체의 패밀리를 작성하기위한 인터페이스를 제공합니다."

의미 : 이와 같은 인터페이스를 제공함으로써 각 제품군 제품의 생성자에 대한 호출이 팩토리 클래스에 캡슐화됩니다. 그리고 이것은 생성자가 호출되는 전체 시스템의 유일한 장소이기 때문에 새로운 팩토리 클래스를 구현하여 시스템을 변경할 수 있습니다. 다른 팩토리를 통해 팩토리 표현을 교환하면 대부분의 코드를 건드리지 않고 전체 제품 세트를 교환 할 수 있습니다.

빌더 패턴 : GoF : "복잡한 객체의 구성을 표현과 분리하여 동일한 구성 프로세스가 다른 표현을 생성 할 수 있습니다."

이것은 무엇을 의미 하는가 : 당신은 감독 (GoF)이라 불리는 다른 클래스의 건설 과정을 요약합니다. 이 디렉터에는 제품의 새 인스턴스를 작성하는 알고리즘이 포함되어 있습니다 (예 : 다른 부품으로 복잡한 제품 작성). 전체 제품의 필수 부분을 작성하기 위해 디렉터는 빌더를 사용합니다. 디렉터에서 빌더를 교환하면 동일한 알고리즘을 사용하여 제품을 작성할 수 있지만 단일 부품의 표현 (및 제품의 표현)을 변경할 수 있습니다. 제품 표현에서 시스템을 확장하거나 수정하려면 새 빌더 클래스를 구현하기 만하면됩니다.

요약하자면 , Abstract Factory Pattern의 목적은 함께 사용하도록 만들어진 일련의 제품을 교환하는 것입니다. 빌더 패턴의 목적은 제품을 다른 표현으로 재사용하기 위해 제품을 작성하는 추상 알고리즘을 캡슐화하는 것입니다.

제 생각에는 추상 팩토리 패턴이 빌더 패턴의 큰 형제라고 말할 수 없습니다. 예, 그것들은 둘 다 창조 패턴이지만 패턴의 주요 의도는 완전히 다릅니다.


좋은 대답, 정교하게 설명하십시오.
towry

"복잡한 객체의 구성과 표현의 분리"
Rajdeep

@ Rajdeep 설명은 의견을 갈망하기 때문에 다른 답변을 썼습니다.
Janis

@Janis 어디에서 읽을 수있는 답이나 출처는 어디입니까?
Rajdeep

- 내가 책 "디자인 패턴"읽어보실 것을 추천 @Rajdeep amazon.de/Patterns-Elements-Reusable-Object-Oriented-Software/...
제니스

7

내가 만들 수있는 빌더와 팩토리의 놀라운 차이점은 다음과 같습니다.

우리가 차를 가지고 있다고 가정

class Car
{
  bool HasGPS;
  bool IsCityCar;
  bool IsSportsCar;
  int   Cylenders;
  int Seats;

  public:
     void Car(bool hasGPs=false,bool IsCityCar=false,bool IsSportsCar=false, int Cylender=2, int Seats=4);
 };

위의 인터페이스에서 다음과 같은 방법으로 자동차를 얻을 수 있습니다.

 int main()
 {
    BadCar = new Car(false,false,true,4,4);
  }

그러나 좌석을 만드는 동안 일부 예외가 발생하면 어떻게됩니까 ?? 당신은 전혀 객체를 얻지 못할 것입니다 // 그러나

다음과 같은 구현이 있다고 가정하십시오.

class Car
 {
    bool mHasGPS;
    bool mIsCityCar;
    bool mIsSportsCar;
    int mCylenders;
    int mSeats;

 public:
    void Car() : mHasGPs(false), mIsCityCar(false), mIsSportsCar(false), mCylender(2), mSeats(4) {}
    void SetGPS(bool hasGPs=false)  {mHasGPs = hasGPs;}
    void SetCity(bool CityCar)  {mIsCityCar = CityCar;}
    void SetSports(bool SportsCar)  {mIsSportsCar = SportsCar;}
    void SetCylender(int Cylender)  {mCylenders = Cylender;}    
    void SetSeats(int seat) {mSeats = seat;}    
};

 class CarBuilder 
 {
    Car* mCar;
public:
        CarBuilder():mCar(NULL) {   mCar* = new Car();  }
        ~CarBuilder()   {   if(mCar)    {   delete mCar;    }
        Car* GetCar()   {   return mCar; mCar=new Car();    }
        CarBuilder* SetSeats(int n) {   mCar->SetSeats(n); return this; }
        CarBuilder* SetCylender(int n)  {   mCar->SetCylender(n); return this;  }
        CarBuilder* SetSports(bool val) {   mCar->SetSports(val); return this;  }
        CarBuilder* SetCity(bool val)   {   mCar->SetCity(val); return this;    }
        CarBuilder* SetGPS(bool val)    {   mCar->SetGPS(val); return this; }
}

이제 이렇게 만들 수 있습니다

 int main()
 {
   CarBuilder* bp =new CarBuilder;
    Car* NewCar  = bp->SetSeats(4)->SetSports(4)->SetCity(ture)->SetGPS(false)->SetSports(true)->GetCar();

     bp->SetSeats(2);

     bp->SetSports(4);

     bp->SetCity(ture);

     bp->SetSports(true)

     Car* Car_II=  bp->GetCar();

  }

두 번째 경우에는 하나의 작업이 실패하더라도 여전히 자동차를 얻습니다.

차가 나중에 완벽하게 작동하지는 않지만 객체가있을 수 있습니다.

Factory Method는 단일 호출로 Car를 제공하지만 Builder는 하나씩 빌드합니다.

그러나 그것은 어느 쪽을 갈지에 대한 신의 요구에 달려 있습니다.


2
틀림없이 유효하지 않은 차보다 차를 전혀 갖지 않는 것이 좋습니다. 휴식 시간을 이용할 때만 문제를 발견하면 어떻게됩니까?
Ken

@ 켄 : 나는 상업 프로젝트 등을 고려하여 좋은 디자인을 주장하지 않으며, 패턴 사이의 차이를 예시하기 위해이 예제를 인용 할 의도입니다. 분명히, 당신은 이것이 나쁜 자동차를 얻는 사용자 경험으로 나쁘다는 것을 정확하지만, 자동차가 제조되는 공장이 있고 일부가 오작동하는 경우 자동차가 생산되지만 나쁜 휴식 시간에 발견되는 것을 고려하십시오. 해당 차량의 테스트 및 고객 배송 시간이 중지되었습니다.
Fooo

2
나는 실제로 빌더 패턴의 열렬한 팬이라는 것을 분명히하고 싶지만, 당신이 주신 이유가 아닙니다. 유효하지 않은 객체는 구성시 실패해야하며 프로세스가 진행 될수록 버그가 더 많이 발견됩니다. 빌더 패턴을 사용하면 필수 데이터가 누락 된 경우 빌드 메소드 (예 : getCar ())에서 예외가 발생하는 것이 일반적입니다.
Ken

7
+-------------------------------------------------------------------+---------------------------------------------------+
|                              Builder                              |                      Factory                      |
+-------------------------------------------------------------------+---------------------------------------------------+
| Return only single instance to handle complex object construction | Retrun various instances on multiple constructors |
| No interface required                                             | Interface driven                                  |
| Inner classes is involved (to avoid telescopic constructors)      | Subclasses are involved                           |
+-------------------------------------------------------------------+---------------------------------------------------+  

텔레 스코핑 생성자 패턴

유추:

  • 공장 : 식당을 생각해보십시오. "오늘의 식사"작성은 공장 패턴입니다. 부엌에 "오늘의 식사를주세요"라고 말하면 부엌 (공장)은 숨겨진 기준에 따라 어떤 객체를 생성할지 결정하기 때문입니다.
  • 빌더 : 사용자 정의 피자를 주문하면 빌더가 나타납니다. 이 경우, 웨이터는 요리사 (빌더)에게 "피자, 치즈, 양파, 베이컨을 넣습니다!" 따라서 빌더는 생성 된 오브젝트가 가져야하는 속성을 노출하지만 설정 방법을 숨 깁니다.

예의


5

BuilderAbstract Factory 는 다른 목적으로 사용되었습니다. 올바른 사용 사례에 따라 적절한 디자인 패턴을 선택해야합니다.

빌더 핵심 기능 :

  1. 빌더 패턴은 간단한 오브젝트를 사용하고 단계별 접근 방식을 사용하여 복잡한 오브젝트를 빌드합니다.
  2. Builder 클래스는 최종 오브젝트를 단계별로 빌드합니다. 이 빌더는 다른 오브젝트와 독립적입니다
  3. 이 시나리오에서 팩토리 메소드 / 추상 팩토리로 대체 : 클라이언트 프로그램에서 팩토리 클래스로 전달하기에 너무 많은 인수로 인해 오류가 발생할 수 있음
  4. 모든 매개 변수를 강제로 전송하는 팩토리와 달리 일부 매개 변수는 선택적 일 수 있습니다.

공장 (간단한 공장) 두드러진 특징 :

  1. 창조 패턴
  2. 상속을 기반으로
  3. 팩토리는 팩토리 메소드 (인터페이스)를 반환하고,이 메소드는 콘크리트 오브젝트를 반환합니다
  4. 새로운 콘크리트 객체를 인터페이스로 대체 할 수 있으며 클라이언트 (호출자)는 모든 구체적인 구현을 인식하지 않아야합니다.
  5. 클라이언트는 항상 인터페이스에만 액세스하며 팩토리 메소드에서 오브젝트 작성 세부 사항을 숨길 수 있습니다.

종종 디자인은 Factory Method를 사용하여 시작하고 (더 복잡하고, 더 커스터마이징 가능하며, 서브 클래스가 확산 됨) Abstract Factory , Prototype 또는 Builder (보다 유연하고 복잡함)로 발전합니다.

관련 게시물을 살펴보십시오.

빌더를 별도의 클래스로 유지 (유창한 인터페이스)

디자인 패턴 : 팩토리 vs 팩토리 메소드 vs 추상 팩토리

자세한 내용은 아래 기사를 참조하십시오.

소스 메이킹

journaldev


5

팩토리 : 팩토리 에 의해 객체의 종속성이 완전히 유지되는 객체의 인스턴스를 만드는 데 사용됩니다. 를 들어 추상 팩토리 패턴 , 같은 추상적 인 공장의 많은 구체적인 구현이 종종있다. 팩토리의 올바른 구현은 의존성 주입을 통해 주입됩니다.

빌더 : 인스턴스화 할 오브젝트의 종속성이 부분적으로 사전에 알려지고 빌더의 클라이언트가 부분적으로 제공 할 때 변경 불가능한 오브젝트 를 빌드하는 데 사용됩니다 .


4

Abstract Factory & Builder 패턴은 모두 창조 패턴이지만 의도가 다릅니다.

Abstract Factory Pattern 은 다음과 같은 경우 관련 객체 패밀리에 대한 객체 생성을 강조합니다.

  • 각 제품군은 공통 기본 클래스 / 인터페이스에서 파생 된 일련의 클래스입니다.
  • 각 객체는 한 번의 호출로 즉시 반환됩니다.

빌더 패턴 은 복잡한 오브젝트를 단계별로 구성하는 데 중점을 둡니다. 복잡한 객체를 구성하는 과정에서 표현을 분리하여 동일한 표현 과정을 다른 표현에 사용할 수 있습니다.

  • Builder 객체는 복잡한 객체의 구성을 캡슐화합니다.
  • Director 오브젝트는 빌더 사용 프로토콜을 알고 있으며 여기서 프로토콜은 복잡한 오브젝트를 빌드하는 데 필요한 모든 논리적 단계를 정의합니다.

"복잡한 객체를 만드는 과정에서 표현을 분리합니다"
Rajdeep

3

복잡한 구성은 구성 할 객체가 추상화로 표시되는 다른 다른 객체로 구성되는 경우입니다.

맥도날드 메뉴를 고려하십시오. 메뉴에는 음료, 메인 및 사이드가 있습니다. 개별 추상화의 어떤 자손이 함께 구성되어 있는지에 따라 작성된 메뉴에는 다른 표현이 있습니다.

  1. 예 : 콜라, 빅맥, 감자 튀김
  2. 예 : 스프라이트, 너겟, 꼬치 튀김

거기에 다른 표현을 가진 메뉴의 두 인스턴스가 있습니다. 차례로 건설 과정은 동일하게 유지됩니다. 음료, 메인 및 사이드가있는 메뉴를 만듭니다.

빌더 패턴을 사용하여 복잡한 오브젝트를 작성하는 알고리즘을 작성하는 데 사용 된 다른 구성 요소와 분리합니다.

빌더 패턴의 관점에서, 알고리즘은 디렉터에서 캡슐화되는 반면 빌더는 필수 부품을 작성하는 데 사용됩니다. 디렉터 알고리즘에서 사용 된 빌더를 변경하면 다른 파트가 메뉴로 구성되므로 다른 표현이됩니다. 메뉴가 생성되는 방식은 동일합니다.


1
이것은 "복잡한 물체의 구성과 표현의 분리"
Rajdeep

2

이들 간의 주요 차이점은 빌더 패턴이다 주로 단계별 복잡한 객체 스텝의 생성을 설명한다. 추상 팩토리 패턴에서 강조하는 것은 객체 제품군입니다 . Builder는 마지막 단계 에서 제품을 반환합니다 . Abstract Factory 패턴에서는 제품을 즉시 사용할 수 있습니다 .

예 : 우리가 미로를 만들고 있다고 가정 해 봅시다.

1. 추상 공장 :

Maze* MazeGame::CreateMaze (MazeFactory& factory) {
Maze* maze = factory.MakeMaze(); /// product is available at start!!
 /* Call some methods on maze */
return maze;
}

2. 제작자 :

Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.buildMaze(); /// We don't have access to maze
 /* Call some methods on builder */
return builder.GetMaze();
}

2

팩토리와 빌더 패턴의 사용법과 차이점은 동일한 코드 기반과 변화하는 요구 사항에 대해 작업하면서 특정 기간에 더 쉽게 이해 / 명확해질 수 있다고 생각합니다.

필자의 경험으로는 일반적으로 비교적 복잡한 초기화 논리를 숨기는 몇 가지 정적 제작자 메서드를 포함하는 팩토리 패턴으로 시작합니다. 객체 계층 구조가 복잡해 지거나 유형, 매개 변수를 더 많이 추가할수록 메서드에 더 많은 매개 변수가 채워 지므로 팩토리 모듈을 다시 컴파일하지 않아도됩니다. 이러한 모든 것들은 생성자 메서드의 복잡성을 증가시키고 가독성을 감소 시키며 생성 모듈을 더욱 취약하게 만듭니다.

이 지점은 전환 / 확장 지점 일 수 있습니다. 이렇게함으로써 구성 매개 변수 주위에 랩퍼 모듈을 작성합니다. 다음 실제 생성 논리를 건드리지 않고 추상화 (추상)와 구현을 더 추가하여 새로운 (유사한) 객체를 나타낼 수 있습니다. 그래서 당신은 "낮은"복잡한 논리를 가졌습니다.

솔직히 말해서, 일종의 "한 단계 또는 여러 단계로 생성 된 객체를 갖는 것은 차이가 있습니다."유일한 다양성 요소는 내가 직면 한 거의 모든 경우에 대해 두 가지 방법을 모두 사용할 수 있기 때문에 구별하기에 충분하지 않기 때문에 지금은 아무런 혜택도 경험하지 않고 있습니다. 이것이 제가 마침내 생각한 것입니다.


2

팩토리 패턴에 비해 빌더 패턴의 주요 장점은 가능한 많은 사용자 정의를 사용하여 일부 표준 오브젝트를 작성하려고하지만 일반적으로 몇 가지만 사용자 정의하는 경우입니다.

예를 들어, HTTP 클라이언트를 작성하려는 경우 기본 쓰기 / 읽기 제한 시간, 프로토콜, 캐시, DNS, 인터셉터 등과 같은 일부 기본 매개 변수를 설정합니다.

클라이언트의 대부분의 사용자는 이러한 기본 매개 변수 만 사용하지만 일부 다른 사용자는 다른 매개 변수를 사용자 정의 할 수 있습니다. 경우에 따라 시간 제한을 변경하고 나머지는 그대로 사용하고 다른 경우에는 캐시와 같은 사용자 지정이 필요할 수 있습니다.

클라이언트를 인스턴스화하는 가능한 방법은 다음과 같습니다 (OkHttpClient에서 가져옴).

//just give me the default stuff
HttpClient.Builder().build()   

//I want to use custom cache
HttpClient.Builder().cache(MyCache()).build() 

//I want custom connection timeout
HttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).build() 

//I am more interested in read/write timeout
HttpClient.Builder()
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS).build()

이를 위해 팩토리 패턴을 사용하는 경우 가능한 모든 생성 매개 변수 조합으로 많은 메소드를 작성하게됩니다. 빌더를 사용하면 관심있는 항목 만 지정하고 다른 모든 매개 변수를 처리 할 수 ​​있도록 빌더를 빌드 할 수 있습니다.


1

빌드 패턴 은 오브젝트 작성의 복잡성 을 강조 합니다 ( "단계"로 해결됨)

추상 패턴은 (복수이지만 관련이있는) 객체의 "추상화"에서 "그냥"을 강조합니다.


1

차이가 분명합니다. 빌더 패턴에서 빌더는 특정 유형의 오브젝트를 작성합니다. 어떤 빌더를 빌드해야하는지 알려야합니다. 팩토리 패턴에서는 추상 클래스를 사용하여 특정 객체를 직접 빌드합니다.

여기서 빌더 클래스는 기본 클래스와 특정 유형 클래스 사이의 중재자 역할을합니다. 더 추상화.


1

둘 다 매우 유사하지만 객체 생성을위한 많은 수의 매개 변수가 있고 일부는 선택적이며 일부 기본값은 선택 사항 인 경우 빌더 패턴으로 이동하십시오.


1

이모

Builder는 좀 더 복잡한 Factory입니다.

그러나 Builder에서 다른 팩토리를 사용하여 객체를 인스턴스화 할 수 있습니다 는 최종적이고 유효한 객체를 빌드하는 데 필요합니다.

따라서 복잡성에 의한 "창조 패턴"진화에 대해 이야기하면 다음과 같이 생각할 수 있습니다.

Dependency Injection Container -> Service Locator -> Builder -> Factory

1

두 패턴 모두 같은 필요성이 있습니다. 일부 클라이언트 코드에서 복잡한 객체의 구성 논리를 숨 깁니다. 그러나 무엇이 "복잡한"(또는 때로는 복잡한) 물체를 만드는가? 주로 의존성 또는보다 부분적인 상태로 구성된 객체의 상태 때문입니다. 초기 객체 상태를 설정하기 위해 생성자별로 의존성을 주입 할 수 있지만 객체는 많은 객체를 필요로 할 수 있습니다. 일부는 기본 초기 상태에 있습니다 (기본 의존성을 null로 설정하는 것이 가장 깨끗한 방법이 아니라는 것을 배웠기 때문에) ) 및 다른 일부는 특정 조건에 의해 구동되는 상태로 설정됩니다. 또한 일종의 "명백한 의존성"인 객체 속성이 있지만 선택적 상태를 가정 할 수도 있습니다.

그 복잡성을 지배하는 잘 알려진 두 가지 방법이 있습니다.

  • 구성 / 집계 : 개체를 구성하고 종속 개체를 구성한 다음 서로 연결합니다. 여기서 빌더는 구성 요소 구성을 이끄는 규칙을 결정하는 프로세스를 투명하고 유연하게 만들 수 있습니다.

  • 다형성 : 구성 규칙은 하위 유형 정의에 직접 선언되므로 각 하위 유형에 대한 규칙 세트가 있으며 일부 조건에 따라 이러한 규칙 세트 중 하나가 오브젝트를 구성하는 데 적용됩니다. 이 시나리오에서는 공장이 완벽하게 적합합니다.

이 두 가지 접근 방식을 혼용하는 것은 없습니다. 제품군은 빌더로 수행 된 오브젝트 작성을 추상화 할 수 있으며 빌더는 팩토리를 사용하여 인스턴스화 할 컴포넌트 오브젝트를 판별 할 수 있습니다.


0

내 의견으로는 빌더 패턴은 다른 많은 객체로부터 객체를 만들려고 할 때 사용되며 부품 생성은 만들려는 객체와 독립적이어야합니다. 빌더에서 클라이언트를 독립적으로 만들기 위해 클라이언트에서 부품 작성을 숨기는 데 도움이됩니다. 복잡한 객체 생성에 사용됩니다 (복잡한 속성으로 구성 될 수있는 객체).

팩토리 패턴은 공통 패밀리의 객체를 작성하고 한 번에 인증하도록 지정합니다. 더 간단한 객체에 사용됩니다.


0

건축업자와 추상 공장

빌더 디자인 패턴은 어느 정도 추상적 팩토리 패턴과 매우 유사합니다. 그렇기 때문에 둘 중 하나가 사용될 때 상황을 차별화 할 수 있어야합니다. 추상 팩토리의 경우 클라이언트는 팩토리의 메소드를 사용하여 자체 오브젝트를 작성합니다. Builder의 경우, Builder 클래스는 오브젝트를 작성하는 방법에 대한 지시를 받고 요청됩니다. 그러나 클래스를 구성하는 방법은 Builder 클래스에 달려 있습니다.이 세부 사항은 두 패턴의 차이를 만듭니다.

제품에 대한 공통 인터페이스

실제로 콘크리트 빌더가 만든 제품은 구조가 크게 다르므로 다른 제품을 파생시킬 이유가없는 경우 공통 상위 클래스입니다. 또한 빌더 패턴과 공통 유형에서 파생 된 오브젝트를 작성하는 추상 팩토리 패턴과 구별됩니다.

출처 : http://www.oodesign.com/builder-pattern.html


-2

팩토리 패턴은 런타임에 클래스의 구체적인 구현을 만듭니다. 즉 주요 목적은 다형성을 사용하여 서브 클래스가 인스턴스화 할 클래스를 결정할 수 있도록하는 것입니다. 이것은 컴파일 타임에 우리가 생성 될 정확한 클래스를 알지 못하는 반면 빌더 패턴은 주로 생성자 안티 패턴의 텔레 스코핑 생성자 문제를 해결하는 것과 관련이 있습니다. 빌더 패턴에는 컴파일 타임에 어떤 객체를 구성하려고하는지 알고 있기 때문에 다형성에 대한 개념이 없습니다.

이 두 패턴의 유일한 공통 주제는 팩토리 메소드 뒤에 생성자와 오브젝트 작성을 숨기고 개선 된 오브젝트 구성을위한 빌드 메소드입니다.


-2

팩토리 패턴을 사용하면 한 번에 한 번에 오브젝트를 작성할 수 있으며 빌더 패턴을 사용하면 오브젝트 작성 프로세스를 중단 할 수 있습니다. 이런 방식으로 객체를 만드는 동안 다른 기능을 추가 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.