В чем разница между шаблоном Builder Design и шаблоном Factory Design? - PullRequest
561 голосов
/ 16 апреля 2009

В чем разница между шаблоном проектирования Builder и шаблоном проектирования Factory?

Какой из них более выгоден и почему?

Как мне представить мои результаты в виде графика, если я хочу проверить и сравнить / сопоставить эти образцы?

Ответы [ 24 ]

409 голосов
/ 16 апреля 2009

При использовании шаблонов проектирования, как правило, не существует «более выгодного» решения, которое подходит для всех случаев. Это зависит от того, что вам нужно реализовать.

Из Википедии:

  • Строитель фокусируется на создании сложный объект шаг за шагом. Аннотация Фабрика подчеркивает семейство продуктов объекты (простые или сложные). Строитель возвращает товар в качестве окончательного шаг, но насколько абстрактно Завод обеспокоен, продукт получает немедленно вернулся.
  • Строитель часто строит Композит.
  • Часто проекты начинаются с использования фабричного метода (менее сложный, более сложный). настраиваемые, подклассы размножаются) и развиваться к абстрактной фабрике, Прототип, или Строитель (более гибкий, более сложный) как дизайнер обнаруживает, где больше гибкости необходимо.
  • Иногда шаблоны творчества дополняют друг друга: Строитель может использовать один из других шаблонов для реализации какие компоненты создаются Аннотация Фабрика, Строитель и Прототип могут использовать синглтон в их Реализации.

Запись в Википедии для шаблона проектирования фабрики: http://en.wikipedia.org/wiki/Factory_method_pattern

Запись в Википедии для шаблона проектирования строителя: http://en.wikipedia.org/wiki/Builder_pattern

286 голосов
/ 22 января 2012

Фабрика - это просто функция-оболочка для конструктора (возможно, в другом классе). Основное отличие состоит в том, что шаблон фабричного метода требует, чтобы весь объект был построен за один вызов метода, а все параметры передаются в одной строке. Конечный объект будет возвращен.

Шаблон компоновщика , с другой стороны, по сути является объектом-оболочкой вокруг всех возможных параметров, которые вы, возможно, захотите передать в вызов конструктора. Это позволяет вам использовать методы установки для медленного построения списка параметров. Еще одним дополнительным методом в классе построителя является метод build (), который просто передает объект построителя в нужный конструктор и возвращает результат.

В статических языках, таких как Java, это становится более важным, когда у вас есть более, чем несколько (потенциально необязательных) параметров, поскольку это позволяет избежать необходимости иметь телескопические конструкторы для всех возможных комбинаций параметров. Также построитель позволяет вам использовать методы установки для определения доступных только для чтения или закрытых полей, которые нельзя изменить напрямую после вызова конструктора.

Базовый заводской пример

// 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");

Пример Basic Builder

// 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

260 голосов
/ 16 апреля 2009

Фабричный шаблон почти можно рассматривать как упрощенную версию шаблона Builder.

В шаблоне Фабрика фабрика отвечает за создание различных подтипов объекта в зависимости от потребностей.

Пользователь фабричного метода не должен знать точный подтип этого объекта. Пример фабричного метода createCar может вернуть объект Ford или Honda.

В шаблоне Builder различные подтипы также создаются методом построителя, но состав объектов может отличаться в пределах одного и того же подкласса.

Чтобы продолжить пример с автомобилем, у вас может быть метод createCar строитель, который создает объект Honda с 4-цилиндровым двигателем или объект Honda с 6 цилиндрами. Шаблон строителя учитывает эту более тонкую гранулярность.

Диаграммы как Pattern Builder , так и Шаблон фабричного метода доступны в Википедии.

54 голосов
/ 16 апреля 2009

Шаблон проектирования строителя описывает объект, который знает, как создать другой объект определенного типа за несколько шагов. Он содержит необходимое состояние для целевого элемента на каждом промежуточном этапе. Подумайте, через что проходит StringBuilder для создания окончательной строки.

Шаблон проектирования фабрики описывает объект, который знает, как создать несколько различных, но связанных видов объектов за один шаг, где конкретный тип выбирается на основе заданных параметров. Подумайте о системе сериализации, где вы создаете ваш сериализатор, и он создает желаемый объект в одном вызове загрузки.

41 голосов
/ 18 июня 2013
  • Построение пошагового сложного объекта: шаблон строителя

  • Простой объект создается с использованием одного метода: шаблон фабричного метода

  • Создание объекта с использованием метода нескольких фабрик: абстрактный шаблон фабрики

14 голосов
/ 17 апреля 2009

Оба являются шаблонами Творения для создания Объекта.

1) Factory Pattern - Предположим, у вас есть один суперкласс и N подклассов. Объект создается в зависимости от того, какой параметр / значение передан.

2) Шаблон Builder - для создания сложного объекта.

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 голосов
/ 09 октября 2017

Pattern Builder и Factory, оба выглядят очень похоже на невооруженные глаза, потому что они оба создают объекты для вас.

Но вам нужно присмотреться

Этот реальный пример прояснит разницу между ними.

Предположим, вы пошли в ресторан быстрого питания и заказали Еда .

1) Какая еда?

Пицца

2) Какие начинки?

стручковый перец, помидор, барбекю курица, NO ананас

Таким образом, различные типы продуктов изготавливаются по фабричному шаблону, но различные варианты (вкусы) конкретного продукта создаются по шаблону Builder.

Различные виды пищи

Пицца, Бургер, Паста

Варианты пиццы

Только сыр, сыр + помидор + стручковый перец, сыр + помидор и т. Д.

Пример кода

Вы можете увидеть пример реализации кода обоих шаблонов здесь
Образец строителя
Заводская модель

10 голосов
/ 15 января 2017

Сначала несколько общих вещей, чтобы следовать моей аргументации:

Основная проблема при разработке больших программных систем заключается в том, что они должны быть гибкими и несложными для изменения. По этой причине существуют некоторые показатели, такие как сцепление и сплоченность. Чтобы создать системы, которые можно легко изменять или расширять по функциональности без необходимости перепроектирования всей системы с нуля, вы можете следовать принципам проектирования (например, SOLID и т. Д.). Через некоторое время некоторые разработчики осознали, что, если они следуют этим принципам, есть некоторые похожие решения, которые хорошо работают для подобных проблем. Этими стандартными решениями оказались шаблоны проектирования.

Таким образом, шаблоны проектирования должны помочь вам следовать общим принципам проектирования для достижения слабосвязанных систем с высокой когезией.

Ответ на вопрос:

Задавая разницу между двумя шаблонами, вы должны спросить себя, какой шаблон делает вашу систему более гибкой. У каждого шаблона есть своя цель - организовать зависимости между классами в вашей системе.

Абстрактный шаблон фабрики: GoF: «Предоставить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов».

Что это значит: Предоставляя такой интерфейс, вызов конструктора каждого продукта семейства инкапсулируется в фабричном классе. И поскольку это единственное место во всей вашей системе, где вызываются эти конструкторы, вы можете изменить свою систему, внедрив новый класс фабрики. Если вы обмениваетесь представлением фабрики через другого, вы можете обмениваться целым набором продуктов, не затрагивая большую часть своего кода.

Образец строителя: GoF: «Отделите построение сложного объекта от его представления, чтобы один и тот же процесс построения мог создавать разные представления».

Что это значит: Вы инкапсулируете процесс построения в другом классе, называемом директором (GoF). Этот директор содержит алгоритм создания новых экземпляров продукта (например, составление сложного продукта из других частей). Для создания составных частей всего продукта директор использует застройщика. Обменив конструктор с директором, вы можете использовать тот же алгоритм для создания продукта, но изменить представления отдельных частей (и, следовательно, представление продукта). Чтобы расширить или изменить свою систему в представлении продукта, все, что вам нужно сделать, это реализовать новый класс компоновщика.

Итак, вкратце: Цель Abstract Factory Pattern - обменяться набором продуктов, которые предназначены для совместного использования. Цель шаблона построителя состоит в том, чтобы инкапсулировать абстрактный алгоритм создания продукта, чтобы повторно использовать его для различных представлений продукта.

По-моему, вы не можете сказать, что Шаблон Абстрактной Фабрики - старший брат Шаблона Строителей. ДА, они оба являются творческими шаблонами, но основная цель шаблонов совершенно иная.

6 голосов
/ 22 августа 2014

Одна поразительная разница между Строителем и фабрикой, которую я смог разглядеть, заключалась в следующем

предположим, у нас есть машина

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);
  }

а что если при создании Seats произойдет какое-то исключение ??? ВЫ НЕ ПОЛУЧИТЕ ОБЪЕКТ ВСЕГО // НО

предположим, что у вас есть реализация, подобная следующей

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 дает вам Автомобиль за один вызов, тогда как Строитель строит один за другим.

Хотя, от того, к какому человеку идти, зависит от нужд соискателя.

4 голосов
/ 15 февраля 2016

Builder и Abstract Factory предназначены для разных целей. В зависимости от правильного варианта использования, вы должны выбрать подходящий шаблон дизайна.

Строитель Существенные особенности:

  1. Шаблон Builder строит сложный объект, используя простые объекты и используя пошаговый подход
  2. Класс Builder строит конечный объект шаг за шагом. Этот строитель не зависит от других объектов
  3. Замена на метод Factory / Abstract Factory в этом сценарии: слишком много аргументов для передачи из клиентской программы в класс Factory, которые могут быть подвержены ошибкам
  4. Некоторые параметры могут быть необязательными, в отличие от Factory, которая заставляет отправлять все параметры

Фабрика (простая Фабрика) существенные особенности:

  1. Творческий паттерн
  2. На основании наследства
  3. Фабрика возвращает фабричный метод (интерфейс), который, в свою очередь, возвращает конкретный объект
  4. Вы можете заменить новые конкретные объекты для интерфейса, и клиент (вызывающая сторона) не должен знать обо всех конкретных реализациях
  5. Клиент всегда имеет доступ только к интерфейсу, и вы можете скрыть детали создания объекта в методе Factory.

Часто проекты начинаются с использования Factory Method (менее сложный, более настраиваемый, подклассы распространяются) и развиваются в направлении Abstract Factory , Prototype или Строитель (более гибкий, более сложный)

Посмотрите на похожие посты:

Удержание строителя в отдельном классе (свободный интерфейс)

Шаблоны проектирования: метод фабрики против фабрики против фабрики абстрактных

Более подробную информацию вы можете найти в следующих статьях:

sourcemaking

journaldev

...