Чи замінені названі аргументи замінюють модель конструктора?


20

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

Builder:

new Builder(requiredA, requiredB).setOptionalA("optional").Build();

Необов’язкові / названі аргументи:

new Object(requiredA, requiredB, optionalA: "optional");

3
Як ви обробляєте 20 необов’язкових аргументів? Існує не проблема, яку повинен вирішити Будівельник, поки вона не набуде значних масштабів. В описуваному вами моменті у вас є два конструктори (і я б не створив Builder для цієї невеликої проблеми).

1
Навіть із необов'язковими аргументами - якщо у конструктора більше 2 аргументів, я віддаю перевагу використанню об’єкта значення для інкапсуляції конфігурації. Те ж саме стосується інтерфейсів рідини та програми для побудови: Все, що перевищує 3, буде замінено об'єктом значення.
Томас Джунк

Відповіді:


21

Будівельники найкорисніші, коли ваш об’єкт потребує великої кількості аргументів / залежностей, щоб бути корисним, або ви хочете дозволити багато різних способів побудови об'єкта.

Зверху в голові я можу уявити, що хтось може захотіти "будувати" об'єкти в 3D-грі, як це:

// Just ignore the fact that this hypothetical god class is coupled to everything ever
new ObjectBuilder(x, y, z).importBlenderMesh("./meshes/foo")
                          .syncWithOtherPlayers(serverIP)
                          .compileShaders("./shaders/foo.vert", "./shaders/foo.frag")
                          .makeDestructibleRigidBody(health, weight)
                          ...

Я можу стверджувати, що цей приклад легше читати за допомогою методів builder, які я створив лише зараз, ніж це було б за додатковими параметрами:

new Object(x, y, z, meshType: MESH.BLENDER,
                    meshPath: "./meshes/foo",
                    serverToSyncWith: serverIP,
                    vertexShader: "./shaders/foo.vert",
                    physicsType: PHYSICS_ENGINE.RIGID_DESTRUCTIBLE,
                    health: health,
                    weight: weight)
                    ...

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


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


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

@ user949300 Я думаю, що ви пропустили важливу частину пункту, а саме те, що методи побудови тут описують взаємозв'язки між параметрами, які втрачаються, якщо у вас є просто маса додаткових параметрів. У прикладі конструктора Ixrec "здоров'я" та "вага", очевидно, логічно є частиною руйнівних налаштувань тіла, але це відношення втрачається в необов'язковій версії аргументу.
Жуль

1
не якщо один із необов'язкових параметрів (body: new DestructibleRigidBody (здоров'я, вага), ...)
Weyland Yutani

@Jules. Що сказав Вейланд - зробіть трохи добре названий конструктор для ваги та зросту.
user949300

8

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

var myThingBuilder = new ThingBuilder("table");
myThingBuilder.setAttribute(Attributes.Legs, 4);

inventoryManager.setPrices(myThingBuilder);

// inventory manager
var availableCheapestMaterial = getMaterial();
myThingBuilder.setMaterial(availableCheapestMaterial);

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


Я не розумію вашого останнього абзацу. Якщо ви "кинете свого будівельника навколо системи, поки вона не буде готова", вона має надто багато знань про систему. Ваш ThingBuilder знає про атрибути, таємничо модифікований InventoryManager та знає про матеріали. Не бачите, як це зменшує знання.
user949300

@ user949300 Подумайте, як було б, не будуючи будівельника по всій системі. Ви б змушені мати клас з величезним фан-фактором, і це просто необхідно для створення речі. (Звичайно, якщо припустити, що ваш клас не зосереджує всіх знань, саме цього ми хотіли уникнути в першу чергу.) Тепер, якщо цей клас несе якусь іншу відповідальність, ви створюєте величезний клас, розбиваючи S у SOLID . Якщо це лише відповідальність, ви робите собі ThingBuilder.
Альфа

1

Це залежить від того, що ти робиш із будівельником.

Якщо ви використовуєте builder просто для встановлення (і зміни) властивостей об'єкта та (відкладання) створення об'єкта, його можна замінити названими парамами.

Заміна конструктора у вас може виникнути компромісність читання / використання, яку @Ixrec надумав (а може і не мати, це залежить від того, що ви робите з будівельником).

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

MockBuilder - приклад, коли його не можна замінити названими парамами. Зі сторінки:

Логіку кроків створення не можна замінити названими парамами


-5

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


3
Так, будівельники чудово підходять для роботи зі складними незмінними об'єктами (або навіть із змінними - вам потрібно переконатися, що об’єкт знаходиться у постійному стані, перш ніж його можна буде використовувати). Однак new Integer(42), new BigDecimal("42.000")і new String("foobar")всі конструктори є незмінними, що ... ну, будівельник був би непотрібним для цих випадків. Таким чином, будівельникові не важливо працювати з незмінними, коли конструктори можуть працювати так само добре.

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

2
Оригінальне запитання нічого не говорить про незмінні предмети. Це питання про названі параметри та взаємозв'язок їх з Builders. Ваша відповідь стосується будівельника та його відношення до незмінних об'єктів. Мені важко бачити, як ваша відповідь відповідає на питання.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.