Чим відрізняється модель дизайну Builder від моделі Factory Design?


663

Яка різниця між схемою дизайну Builder від схемою дизайну Factory?

Хто з них вигідніший і чому?

Як я можу представити свої результати як графік, якщо хочу перевірити та порівняти / порівняти ці зразки?


13
Оскільки вони роблять різні речі, що ви маєте на увазі під «вигідним»?
S.Lott

5
Builder - це більш складна версія конструктора - тоді як заводський метод - спрощений.
Давид Хорват

@ DávidHorváth Я б не назвав Builder як "складніший". Якщо ви маєте справу з конструктором, який має 100 параметрів, і вам цікаво лише 3 з них, і ви знаєте, що кількість параметрів може змінитися в майбутньому, використання шаблону Builder зробить життя кожного набагато простішим.
Ненормальна

@ Aberrant Складне використання та архітектурна складність - це дві різні речі. Я зосередився на останньому.
Давид Хорват

Відповіді:


466

Що стосується дизайнерських моделей, зазвичай не існує "більш вигідного" рішення, яке працює для всіх випадків. Це залежить від того, що потрібно здійснити.

З Вікіпедії:

  • Будівельник фокусується на побудові складного об'єкта поетапно. Анотація Фабрика підкреслює сімейство товарних об'єктів (простих чи складних). Builder повертає продукт як завершальний крок, але що стосується абстрактної фабрики, то продукт повертається негайно.
  • Будівельник часто будує Композит.
  • Часто проекти починають використовувати заводський метод (менш складний, більш настроюваний, підкласи розповсюджуються) і розвиваються в напрямку абстрактних заводів, прототипів або будівельників (більш гнучких, складніших), оскільки дизайнер виявляє, де потрібна більша гнучкість.
  • Іноді креативні моделі є додатковими: Builder може використовувати один з інших шаблонів, щоб реалізувати, які компоненти будуються. Анотація Factory, Builder та Prototype можуть використовувати Singleton у своїх реалізаціях.

Запис у Вікіпедії для фабричного дизайну: http://en.wikipedia.org/wiki/Factory_method_pattern

Запис у Вікіпедії для моделі дизайну розробника: http://en.wikipedia.org/wiki/Builder_pattern


159
Це саме різниця. Builder потрібен лише тоді, коли об'єкт неможливо створити за один крок. Одним чудовим прикладом цього може бути процес десеріалізації складного об'єкта. Часто параметри складного об'єкта повинні бути знайдені по черзі.
Бернар Ігірі

1
У першому реченні я б сказав, що тут абсолютно часто є більш вигідне рішення, яке широко застосовується ... ми просто не бачимо цього, оскільки вони перетворюються безпосередньо на мови програмування.
Joel Coehoorn

4
@Joel: Я погоджуюся, що деякі зразки частіше зустрічаються, ніж інші (наприклад, Factory здається більш поширеним, ніж Builder), але я мав на увазі те, що жодна з них не завжди краща за іншу, незалежно від того, як виглядає сценарій. .
Адріан Григоре

@AdrianGrigore що робити, якщо змішати їх обох ?? aso.net mvc мають ControllerBuilder, який встановив і отримає метод для класу ControllerFactory
AminM

Відповідь Goood, хоча 2 речі, які варто додати: 1) Builder використовується в основному для створення POJO, використовуючи Fluent API (наприклад, Person.builder (). WithName ("Sam"). WithAge (38) .build (). 2) В моєму досвіді, builder корисний для створення POJO для об’єктів домену, тоді як завод корисний для створення службових об'єктів, таких як клас PdfGeneratorFactory. Об'єкт обслуговування може бути кешований у межах фабрики протягом більше одного разу, тоді як будівельник завжди створює новий об'єкт за задумом.
saurabh.in

359

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

З іншого боку, модель будівельника є, по суті, об'єктом обгортки навколо всіх можливих параметрів, які ви можете передати в виклик конструктора. Це дозволяє використовувати методи встановлення для повільного складання списку параметрів. Один додатковий метод класу builder - це метод build (), який просто передає об'єкт builder в потрібний конструктор і повертає результат.

У статичних мовах, таких як 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");

Приклад базового конструктора

// 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, навіть у посиланні на wiki, яке ви використовували, є інше. Цей FruitBuilder - це деяка суміш компонентів Director та Builder, де ви викликаєте build (), який повинен належати до Director та setters, що належать до компонента Builder. Директор повинен містити ділову логіку щодо того, як створити об’єкт за допомогою методів Builders. Вільні apis не є шаблонами для будівельників, а StringBuilder також не є дизайнером.
Кмачек

282

Фабричний шаблон майже можна розглядати як спрощену версію шаблону Builder.

За фабричним зразком фабрика відповідає за створення різних підтипів об'єкта залежно від потреб.

Користувачу фабричного методу не потрібно знати точний підтип цього об’єкта. Приклад заводського методу createCarможе повернути об'єкт Fordабо Hondaнабраний.

У шаблоні Builder різні підтипи також створюються методом builder, але склад об'єктів може відрізнятися в межах одного підкласу.

Для продовження прикладу автомобіля у вас може бути createCarметод будівельника, який створює об'єкт- Hondaтип з 4-циліндровим двигуном або Honda-типовий об'єкт з 6 циліндрами. Шаблон конструктора дозволяє досягти такої тонкої деталізації.

Діаграми як моделі Builder, так і фабричного методу доступні у Вікіпедії.


13
Шаблон будівельника схожий на збільшення масштабу будівництва великого об'єкта. Великий об'єкт складається з іншого об'єкта, який складається далі як подібна рекурсія. У той час як фабрика просто отримає вам річ ​​за один дзвінок. Чи правильно це розуміння?
Fooo

63

Шаблон дизайну конструктора описує об'єкт, який знає, як створити інший об'єкт певного типу протягом декількох кроків. Він містить необхідний стан для цільового елемента на кожному проміжному кроці. Подумайте, через що проходить StringBuilder, щоб отримати остаточний рядок.

Фабрична схема дизайну описує об'єкт, який знає, як створити кілька різних, але пов'язаних між собою видів об'єктів за один крок, де конкретний тип вибирається виходячи із заданих параметрів. Подумайте про систему серіалізації, де ви створюєте свій серіалізатор, і він конструює потрібне в об'єкті все за один виклик завантаження.


7
Лише якийсь натяк: хорошим прикладом для шаблону для будівельника є "вільний інтерфейс", а ADO.NET повна "фабричних" та "абстрактних заводських" реалізацій (тобто DbFactory).
бой

50
  • Побудова складного об'єкта поетапно: побудова малюнка

  • Простий об’єкт створюється за допомогою одного методу: заводський метод шаблону

  • Створення об'єкта за допомогою декількох заводських методів: абстрактний заводський візерунок


21

Зображення Builder і Factory pattern - обидва схожі на неозброєні очі, оскільки вони обидва створюють для вас об’єкти.

Але потрібно придивитися ближче

Цей приклад із реального життя зробить різницю між двома більш зрозумілими.

Припустимо, ви зайшли в ресторан швидкого харчування і замовили їжу .

1) Яка їжа?

Піца

2) Які начинки?

Capsicum, помідор, курятина для барбекю, НЕ БУДУТЬ

Так різні страви виготовляються за фабричним малюнком, але різні варіанти (ароматизатори) певної їжі виробляються за допомогою моделі Builder.

Різні види їжі

Піца, бургер, паста

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

Тільки сир, сир + помідор + капсикум, сир + помідор і т.д.

Зразок коду

Ви можете побачити приклад реалізації коду обох моделей тут
Builder шаблон
Factory Pattern


1
Дякуємо, що надали зразок коду! Ваші приклади дуже добре розрізняють ці 2 структури.
Роммель Парас

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). Цей директор містить алгоритм створення нових екземплярів продукту (наприклад, складіть складний продукт з інших частин). Для створення цілісних частин усього продукту режисер використовує конструктор. Обмінюючи програму-конструктор, ви можете використовувати один і той же алгоритм для створення продукту, але змінювати уявлення про окремі частини (і так представлення продукту). Щоб розширити або змінити систему в представленні продукту, все, що вам потрібно зробити, - це впровадити новий клас будівельників.

Отже, коротше: мета абстрактного заводу - обмін набором продуктів, які виготовляються для спільного використання. Мета Шаблон Builder полягає в інкапсуляції абстрактного алгоритму створення продукту для його повторного використання для різних представлень продукту.

На мою думку, ви не можете сказати, що абстрактний заводський візерунок є старшим братом моделі будівельника. ТАК, вони обидва креативні зразки, але головна мета шаблонів зовсім інша.


приємна відповідь, детально поясніть.
буксирування

Ви можете пояснити, будь ласка, значення "Відокремити побудову складного об'єкта від його подання"
Rajdeep

@Rajdeep пояснення полягає в тому, щоб чекати коментарів, тому я написав ще одну відповідь.
Яніс

@Janis Де ця відповідь чи джерело, звідки я можу прочитати?
Rajdeep

@Rajdeep я рекомендую вам прочитати книгу „Шаблони дизайну” - amazon.de/Patterns-Elements-Reusable-Object-Oriented-Software/…
Janis

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

  }

Тут, у другому випадку, навіть якщо одна операція не вдасться, ви все одно отримаєте Автомобіль.

Можливо, ця машина не спрацює ідеально пізніше, але, ви б мали це об'єкт.

Тому що заводський метод дає вам Автомобіль за один дзвінок, тоді як Будівельник будує по черзі.

Хоча, це залежить від потреб дизайну, на кого саме йти.


2
Безумовно, що краще взагалі не мати автомобіля, ніж недійсний автомобіль - що робити, якщо проблему ви виявите лише тоді, коли приїдете використовувати перерви?
Кен

@Ken: Я не наполягаю на тому, щоб його гарний дизайн був перспективним комерційним проектом тощо, а саме наміром описати цей приклад, щоб пояснити різницю між моделями. Ви, безумовно, маєте рацію, що це погано з досвіду користувачів, що потрапляє поганий автомобіль, але, врахуйте, є завод, в якому зроблені машини і якась частина несправності, то машина все-таки виробляється, але з поганою перервою, яка виявилася б на час тестування та доставки цього автомобіля до замовника припиняється.
Fooo

2
Я хотів би уточнити, що я насправді великий шанувальник шаблону будівельника, однак не з тієї причини, яку ви вказали. Об'єкт, який недійсний, повинен вийти з ладу під час будівництва, чим далі буде виявлено помилку, тим дорожче вона. З малюнком конструктора було б нормально, щоб метод збирання (у вашому прикладі під назвою getCar ()) кинув виняток, якщо відсутні якісь необхідні дані.
Кен

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

Модель телескопічного конструктора

Аналогія:

  • Фабрика: Розгляньте ресторан. Створення «сьогоднішньої страви» - це заводський зразок, оскільки ви кажете на кухні «дістаньте мені сьогоднішню страву», а кухня (фабрика) вирішує, який об’єкт створити, грунтуючись на прихованих критеріях.
  • Builder: будівельник з’являється, якщо ви замовляєте власну піцу. У цьому випадку офіціант каже шеф-кухарю (будівельнику) "мені потрібна піца; додайте в неї сир, цибулю та бекон!" Таким чином, будівельник розкриває атрибути, які повинен мати створений об'єкт, але приховує, як їх встановити.

Люб'язно


5

Будівельник і абстрактна фабрика призначені для різних цілей. Залежно від правильного випадку використання, ви повинні вибрати відповідний шаблон дизайну.

Особливості будівельника :

  1. Шаблон Builder будує складний об'єкт, використовуючи прості об'єкти та використовуючи покроковий підхід
  2. Клас Builder будує кінцевий об'єкт поетапно. Цей будівельник не залежить від інших об'єктів
  3. Заміна на заводський метод / Абстрактний завод у цьому сценарії: Занадто багато аргументів для передачі від клієнтської програми до класу Factory, які можуть бути схильними до помилок
  4. Деякі параметри можуть бути необов'язковими на відміну від Factory, які змушують надсилати всі параметри

Основні характеристики заводу (простий завод):

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

Часто проекти починають використовувати заводський метод (менш складний, більш настроюваний, підкласи розповсюджуються) та розвиваються до абстрактних заводських , прототипових або будівельників (більш гнучких, складніших)

Подивіться на пов’язані публікації:

Ведення будівельника в окремому класі (вільний інтерфейс)

Шаблони дизайну: Фабрика проти заводського методу проти абстрактного заводу

Докладнішу інформацію можна знайти в статті нижче:

створення джерел

журналдев


5

Фабрика : використовується для створення екземпляра об'єкта, коли залежність об'єкта повністю утримується заводом. Для абстрактного заводського зразка часто існує багато конкретних реалізацій тієї ж абстрактної фабрики. Правильна реалізація фабрики вводиться через ін'єкцію залежності.

Builder : використовується для побудови незмінних об'єктів, коли залежності об'єкта, що підлягає встановленню, частково відомі заздалегідь, а частково забезпечуються клієнтом будівельника.


4

Абстрактний малюнок Factory & Builder - це як креативні моделі, але з різними намірами.

Абстрактний заводський візерунок наголошує на створенні об'єктів для сімей пов'язаних об'єктів, де:

  • Кожна сім'я - це набір класів, похідних від загального базового класу / інтерфейсу.
  • Кожен об’єкт повертається негайно в результаті одного дзвінка.

Шаблон будівельника фокусується на побудові складного об'єкта поетапно. Це відокремлює подання від процесу побудови складного об'єкта, так що той самий процес побудови може бути використаний для різних уявлень.

  • Об'єкт Builder інкапсулює конфігурацію складного об'єкта.
  • Об'єкт Director знає протокол використання Builder, де протокол визначає всі логічні кроки, необхідні для побудови складного об'єкта.

Ви можете, будь ласка, пояснити значення "відв'язує подання від процесу побудови складного об'єкта"
Rajdeep

3

Складна конструкція - це коли об'єкт, що будується, складається з різних інших об'єктів, які представлені абстракціями.

Розглянемо меню в Макдональдсі. Меню містить напій, головний та бічний. Залежно від того, які нащадки окремих абстракцій складаються разом, створене меню має ще одне подання.

  1. Приклад: кола, біг-мак, картопля фрі
  2. Приклад: спрайт, нагетси, фігурні фрі

Там ми отримали два екземпляри меню з різними поданнями. Процес будівництва в свою чергу залишається колишнім. Ви створюєте меню з напоєм, головним і бічним.

Використовуючи шаблон конструктора, ви відокремлюєте алгоритм створення складного об'єкта від різних компонентів, що використовуються для його створення.

З точки зору схеми побудови, алгоритм інкапсульований у директорі, тоді як будівельники використовуються для створення цілісних частин. Змінення використовуваного конструктора в алгоритмі директора призводить до різного представлення, оскільки інші частини складаються з меню. Спосіб створення меню залишається тим самим.


1
Це пояснює "відокремлення конструкції складного об'єкта від його представлення"
Радждейп

2

Основна відмінність між ними полягає в тому, що візерунок Builder в першу чергу описує створення складних об'єктів поетапно. У абстрактному заводському зразку акцент робиться на родини предметів-виробів . Builder повертає продукт на останньому кроці . Перебуваючи в абстрактній заводській схемі, продукт доступний відразу .

Приклад: Скажімо, що ми створюємо Maze

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

Я вважаю, використання та різницю між моделями Factory & Builder можна зрозуміти / уточнити легше за певний проміжок часу, коли ви працювали над тією ж базою коду та змінюючи вимоги.

З мого досвіду, як правило, ви починаєте з заводської схеми, що включає пару статичних методів створення, щоб передусім приховати порівняно складну логіку ініціалізації. Оскільки ваша ієрархія об'єктів стає складнішою (або при додаванні більше типів, параметрів), ви, ймовірно, отримаєте свої методи заповнені більшою кількістю параметрів, і не кажучи вже про те, що вам доведеться перекомпілювати заводський модуль. Всі ці речі, збільшують складність методів ваших творців, зменшують читабельність та роблять модуль створення більш крихким.

Ця точка, можливо, буде точкою переходу / розширення. Роблячи це, ви створюєте модуль обгортки навколо параметрів побудови, і тоді ви зможете представляти нові (подібні) об’єкти, додаючи ще кілька абстракцій (можливо) та реалізацій, не торкаючись фактичної логіки створення. Отже, у вас була "менш" складна логіка.

Відверто кажучи, посилаючись на щось таке, що "мати об'єкт, створений в один крок або кілька кроків, є різницею", оскільки єдиний фактор різноманітності не був достатнім для їх розрізнення, оскільки я міг використовувати обидва способи майже для всіх випадків, з якими стикався тепер, не відчуваючи ніякої користі. Тож це я остаточно подумав про це.


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

Обидва дуже схожі, але якщо у вас є велика кількість параметрів для створення об'єктів, деякі з них необов'язкові з деякими значеннями за замовчуванням, перейдіть до шаблону Builder.


1

ІМХО

Будівельник - якась більш складна Фабрика.

Але в Builder ви можете інстанціювати об'єкти за допомогою інших заводів , необхідних для створення остаточного та дійсного об'єкта.

Отже, говорячи про еволюцію "креативних моделей" за складністю, ви можете подумати про це таким чином:

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

1

Обидві моделі мають однакову необхідність: приховати від якогось клієнтського коду логіку побудови складного об'єкта. Але що робить «складний» (або, іноді, ускладнюючий) об’єкт? Головним чином, це обумовлено залежностями, а точніше станом об'єкта, складеним більш частинними станами. Ви можете вводити залежності конструктором для встановлення початкового стану об'єкта, але об’єкт може потребувати їх багато, деякі будуть у початковому стані за замовчуванням (лише тому, що ми повинні були дізнатись, що встановити залежність за замовчуванням до нуля не найчистіший спосіб ) та деякий інший встановлений стан, керований якоюсь умовою. Більше того, існують об'єктні властивості, які є деякими "невиразними залежностями", але вони також можуть приймати необов'язкові стани.

Є два відомих способи домінування над цією складністю:

  • Склад / агрегація: Побудуйте об’єкт, побудуйте його залежні об'єкти, а потім з'єднайте. Тут будівельник може зробити прозорим і гнучким процес, який визначає правила, що керують побудовою компонента.

  • Поліморфізм: правила побудови оголошуються безпосередньо під визначення підтипу, тому у вас є набір правил для кожного підтипу, і деяка умова визначає, яке з цих наборів правил застосовується для побудови об'єкта. Завод ідеально вписується в цей сценарій.

Ніщо не заважає змішати ці два підходи. Сімейство продуктів може абстрагувати створення об'єктів, виконане з будівельником, будівельник може використовувати фабрики для визначення, який компонентний об'єкт інстанціювати.


0

На мою думку, шаблон Builder використовується тоді, коли ви хочете створити об’єкт із купки інших об’єктів, і створення частини повинно бути незалежним від об'єкта, який ви хочете створити. Це допомагає приховати створення частини від клієнта, щоб зробити будівельника та клієнта незалежними. Він використовується для створення складних об'єктів (об'єктів, які можуть складатися зі складних властивостей)

Хоча заводський зразок вказує, що ви хочете створити об'єкти загальної родини, і ви хочете, щоб це було одразу керовано. Він використовується для більш простих об'єктів.


0

Будівельник і абстрактний завод

Шаблон дизайну Builder дуже схожий, певною мірою, на абстрактний заводський візерунок. Ось чому важливо вміти розрізняти ситуації, коли використовується та чи інша. У випадку з "Фабрика абстрактних" клієнт використовує фабричні методи для створення власних об'єктів. У випадку Builder клас Builder вказується, як створити об’єкт, а потім його запитують, але спосіб складання класу залежить від класу Builder, і ця деталь робить різницю між двома шаблонами.

Загальний інтерфейс для продуктів

На практиці вироби, створені бетонниками, мають суттєво різну структуру, тому, якщо немає причин отримувати різні продукти, загальний батьківський клас. Це також відрізняє модель "Builder" від "абстрактної фабрики", яка створює об'єкти, отримані із загального типу.

Від: http://www.oodesign.com/builder-pattern.html


-2

Фабрична схема створює конкретну реалізацію класу під час виконання, тобто його головний намір полягає у використанні поліморфізму для того, щоб підкласи могли вирішити, який клас інстанціювати. Це означає, що під час компіляції ми не знаємо точного класу, який буде створено, тоді як модель Builder в основному стосується вирішення проблеми телескопічних конструкторів антипатерн, яка виникає через велику кількість необов'язкових полів класу. У схемі конструктора немає поняття поліморфізму, оскільки ми знаємо, який об’єкт ми намагаємося побудувати під час компіляції.

Єдиною поширеною темою цих двох шаблонів є приховування конструкторів та створення об'єктів за заводськими методами та методом побудови для поліпшення побудови об'єктів.


-2

Фабричний візерунок дозволяє вам створювати об’єкт відразу, тоді як модель розробника дозволяє вам порушити процес створення об'єкта. Таким чином ви можете додати різну функціональність під час створення об’єкта.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.