LINUX.ORG.RU

Вопрос по паттерну «строитель»

 , ,


1

1

Вот по этой статье пытаюсь осиливать

https://ru.wikipedia.org/wiki/Строитель_(шаблон_проектирования)#.D0.A6.D0.B5....

Такая вот заморочка с птичьим языком

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

Что они тут подразумевают под «представлением»? У нас разве в результате конструирования объекта не получаются разные представления? Что это за хрень вообще — представление?

То есть, исходя из этой цитаты, получается, что без билдера у нас конструирование объекта и его «представление» — это одно и то же что-ли?

Далее

Плюсы позволяет изменять внутреннее представление продукта; изолирует код, реализующий конструирование и представление; дает более тонкий контроль над процессом конструирования.

Ни один из этих пунктов не понятен. Первый — это опять же «представление» — что это такое. Второе — изолирует. Вопрос — изолирует от чего? Третье — в чем конкретно проявляется «более тонкий контроль над процессом конструирования»?

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

Может быть примеры неудачные? В чем на самом деле смысл данного шаблона?

Спасибо.



Последнее исправление: somequest (всего исправлений: 1)

Угадал по третьему слову. Но сначала угадал по первому тегу. Почему ещё не в бане?

Solace ★★
()
Ответ на: комментарий от Solace

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

anonymous
()

Что это за хрень вообще — представление?

Это как множество характеристик, которыми обладает в какой-то момент обьект. Можно так сказать

Вопрос — изолирует от чего?

Это такая защита от дебила, который может неправильно что-то инициализировать

более тонкий контроль над процессом конструирования

Например можно инициализировать несколько полей всего одним методом или выполнить какую-то сложную логику после вызова конструктора

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

I60R ★★
()

The intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern. The telescoping constructor anti-pattern occurs when the increase of object constructor parameter combination leads to an exponential list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once.

asaw ★★★★★
()
Ответ на: комментарий от asaw

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

somequest
() автор топика
Ответ на: комментарий от somequest

Идея - вынести конструктов в отдельную сущность, чьим поведением можно оперировать в рантайме.

Это всё равно что switch case на полиморфизм заменить. Или например 5 параметров в функции, где потом ещё 6ой и 7ой потенциально появятся заменить на структуру.

Более того, т.к. конструктор становиться отдельной сущностью, никто не мешает конструировать конструкторы. Но это уже для наркоманов имхо или для чего то архимонструозного.

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

Довольно тухлая аналогия, но похоже примерно как в c++ operator new или аллокатор и собственно конструктор. new отжирает память для обьекта и возвращает указатель на него, а конструктор инициализирует эту память. Память в данном случае то самое «представление».

pon4ik ★★★★★
()
Ответ на: комментарий от somequest

Билдер придумали чтобы не писать много конструкторов на всякий случай жизни, например

 
class A {
    public A () { ... }
    public A (A) { ... }
    public A (B) { ... }
    public A (C) { ... }
    public A (A, B) { ... }
    public A (A, C) { ... }
    public A (A, B, C) { ... }
} 
вместо этого используют Builder'ы
    A a = new A.Builder().build();
    A with_A = new A.Builder().with_A(A).build();
    A with_A_and_B = new A.Builder().with_A(A).with_B(B).build();

I60R ★★
()
Последнее исправление: I60R (всего исправлений: 1)

Что они тут подразумевают под «представлением»?

Формат исходных данных для конструирования объекта. Под внутренним представлением понимается то, как там внутри объекта всё устроено. Т.о. билдер позволяет использовать разные представления данных для инициализации объекта независимо от его внутренней структуры.

Пример: ты пишешь графическую библиотеку, у тебя есть объект «точка» и объект «фигура», который состоит из набора точек. Допустим ты решил использовать в объекте «фигура» список точек, соответственно ты пишешь конструктор, который принимает такой список. Всё хорошо, но когда тебе нужно сделать фигуру из 100500 точек тебе придётся вручную создавать объекты точек, добавлять их в список, потом вызывать конструктор фигуры и т.п. геморрой. И тут ты вспоминаешь, что у тебя есть специально обученные мартышки люди, которые могут забахать описание фигуры в yaml. Ты радостно пишешь метод, который принимает описание фигуры на yaml, конструирует точки, запихивает их в список и вызывает конструктор фигуры. Так вот это и есть билдер. Профит в том, что если тебе нужно будет переобуться с yaml на xml, то нет никаких проблем, пишешь второй билдер для xml и конкретный экземпляр билдера получаешь из фабрики (ну как обычно). При этом в код класса фигуры тебе лезть вообще не нужно. Такие дела.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

Разлогинился,и думаешь, тебя не видно, хуепутало?

anonymous
()

Примеры в википедии и впрямь неудачные.

Глянь, например, примеры из книги Фаулера «Предметно-ориентированные языки программирования», его статью «Спецификация» (где-то на сайте там у него была), пример того как работает QueryBuilder в Java.

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

И действительно, элементарный пример: класс Expression имеет элементарное поведение - один метод: Value eval(Environment env). Он ничего не знает о том, как он был сконструирован, и как из него сконструировать другие Expression-ы. Зато ExpressionBuilder имеет поведение для конструирования: ExpressionBuilder add(ExpressionBuilder b1, ExpressionBuilder b2) и т.п. и оконечный метод Expression build().

anonymous
()

Еще один профит от «применения» паттерна построитель - производительность. Это можно отметить неоднократно при использовании QueryBuilder-а в Java. Запрос в нем строится однократно, потом в построенный запрос можно передавать значения параметров и вызывать его с различными параметрами. Это быстрее, чем строить запрос каждый раз.

Проблема с производительностью может вообще оказаться решающей в вопросе - «применять» этот паттерн или нет? И хотя это не основное назначение паттерна, но при его использовании можно отложить всю трудоемкую работу по конструированию объекта до того момента, когда результаты конструирования будут необходимы.

anonymous
()

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

Когда API конструирования отделено от API поведения объекта, мы действительно можем менять поведение не меняя методов конструирования. Но на мой взгляд, это не самое главное.

«Изолирует» - «представление» и «конструирование» - стало быть друг от друга.

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.