Каковы некоторые распространенные , реальные примеры использования шаблона Builder? Что он тебе покупает? Почему бы просто не использовать фабричный шаблон?
java
design-patterns
builder
Чарльз Грэм
источник
источник
Ответы:
Ключевое различие между сборщиком и фабрикой IMHO заключается в том, что сборщик полезен, когда вам нужно много чего сделать, чтобы построить объект. Например, представьте DOM. Вы должны создать множество узлов и атрибутов, чтобы получить конечный объект. Фабрика используется, когда фабрика может легко создать весь объект за один вызов метода.
Одним из примеров использования компоновщика является создание XML-документа. Я использовал эту модель при построении фрагментов HTML, например, у меня может быть Builder для построения таблицы определенного типа, и он может иметь следующие методы (параметры не показаны). :
Затем этот конструктор выложит мне HTML. Это гораздо легче прочитать, чем пройти через большой процедурный метод.
Проверьте Шаблон Строителя в Википедии .
источник
Ниже приведены некоторые причины, приводящие доводы в пользу использования шаблона и примера кода в Java, но это реализация шаблона Builder, охватываемого бандой четырех в шаблонах проектирования. . Причины, по которым вы будете использовать его в Java, также применимы и к другим языкам программирования.
Как утверждает Джошуа Блох в Effective Java, 2nd Edition :
В какой-то момент мы все столкнулись с классом со списком конструкторов, где каждое добавление добавляет новый параметр option:
Это называется паттерном телескопического конструктора. Проблема с этим шаблоном состоит в том, что, если конструкторы имеют длину 4 или 5 параметров, становится трудно запомнить требуемый порядок параметров, а также какой конкретный конструктор вам может потребоваться в данной ситуации.
Одной альтернативой шаблону телескопического конструктора является шаблон JavaBean, в котором вы вызываете конструктор с обязательными параметрами, а затем вызываете любые дополнительные сеттеры после:
Проблема здесь заключается в том, что, поскольку объект создается за несколько вызовов, он может находиться в несогласованном состоянии в процессе его создания.Это также требует много дополнительных усилий для обеспечения безопасности резьбы.
Лучшая альтернатива - использовать шаблон Builder.
Обратите внимание, что Pizza является неизменным и все значения параметров находятся в одном месте . Поскольку методы сеттера Builder возвращают объект Builder, они могут быть связаны .
В результате получается код, который легко написать, а также легко прочитать и понять. В этом примере метод сборки может быть изменен для проверки параметров после их копирования из компоновщика в объект Pizza и создания исключения IllegalStateException, если указано недопустимое значение параметра. Этот шаблон является гибким, и в будущем к нему легко добавить больше параметров. Это действительно полезно, только если у вас будет более 4 или 5 параметров для конструктора. Тем не менее, это может быть стоит в первую очередь если вы подозреваете, что, возможно, добавите больше параметров в будущем.
Я много позаимствовал на эту тему из книги Джошуа Блоха « Эффективная Java», 2-е издание . Чтобы больше узнать об этом шаблоне и других эффективных методах Java, я настоятельно рекомендую его.
источник
new Pizza.Builder(12).cheese().pepperoni().bacon().build();
Pizza.Builder(12).cheese().pepperoni().bacon().build();
вам нужно будет перекомпилировать свой код или иметь ненужную логику, если вам нужны только пепперони пицц. По крайней мере, вы также должны предоставить параметризованные версии, такие как первоначально предложенный @Kamikaze Mercenary.Pizza.Builder(12).cheese(true).pepperoni(false).bacon(false).build();
, Опять же, мы никогда не тестируем юнит, не так ли?Рассмотрим ресторан. Создание «сегодняшней еды» - это фабричный шаблон, потому что вы говорите кухне «принесите мне сегодняшнюю еду», а кухня (фабрика) решает, какой объект генерировать, основываясь на скрытых критериях.
Строитель появится, если вы закажете заказную пиццу. В этом случае официант говорит шеф-повару (строителю): «Мне нужна пицца; добавь в нее сыр, лук и бекон!» Таким образом, конструктор предоставляет атрибуты, которые должен иметь сгенерированный объект, но скрывает, как их устанавливать.
источник
Класс .NET StringBuilder является отличным примером шаблона компоновщика. В основном это используется для создания строки в серии шагов. Конечный результат, который вы получаете при выполнении ToString (), всегда является строкой, но создание этой строки зависит от того, какие функции в классе StringBuilder были использованы. Подводя итог, основная идея состоит в том, чтобы создавать сложные объекты и скрывать детали реализации того, как он создается.
источник
b.append(...).append(...)
перед окончательным вызовомtoString()
. Образец цитирования: infoq.com/articles/internal-dsls-javaДля многопоточной задачи нам нужно было создать сложный объект для каждого потока. Объект представляет обрабатываемые данные и может меняться в зависимости от ввода пользователя.
Можем ли мы использовать фабрику вместо этого? да
Почему не мы? Строитель имеет больше смысла, я думаю.
Фабрики используются для создания различных типов объектов, имеющих одинаковый базовый тип (реализуют один и тот же интерфейс или базовый класс).
Строители строят один и тот же тип объекта снова и снова, но конструкция является динамичной, поэтому ее можно изменять во время выполнения.
источник
Вы используете его, когда у вас есть много вариантов для решения. Думайте о вещах как jmock:
Это кажется намного более естественным и ... возможно.
Есть также сборка XML, сборка строк и многое другое. Представь, если
java.util.Map
бы поставил как строитель. Вы можете сделать что-то вроде этого:источник
Проходя через фреймворк Microsoft MVC, я подумал о шаблоне компоновщика. Я наткнулся на шаблон в классе ControllerBuilder. Этот класс должен возвращать фабричный класс контроллера, который затем используется для создания конкретного контроллера.
Преимущество использования компоновщика в том, что я вижу, в том, что вы можете создать собственную фабрику и вставить ее в фреймворк.
@Tetha, может быть ресторан (Framework), управляемый итальянским парнем, который подает пиццу. Для приготовления пиццы итальянский парень (Object Builder) использует Owen (Factory) с основанием для пиццы (базовый класс).
Теперь индийский парень принимает ресторан у итальянского парня. Индийский ресторан (Framework) на серверах доши вместо пиццы. Для приготовления досы индийский парень (строитель объектов) использует сковороду (фабрика) с майдой (базовый класс)
Если вы посмотрите на сценарий, еда отличается, способ приготовления пищи отличается, но в том же ресторане (в тех же рамках). Ресторан должен быть построен таким образом, чтобы он мог поддерживать китайскую, мексиканскую или любую кухню. Конструктор объектов внутри фреймворка облегчает плагин того вида кухни, который вы хотите. например
источник
Мне всегда не нравился шаблон Builder как нечто громоздкое, навязчивое и очень часто злоупотребляемое менее опытными программистами. Это шаблон, который имеет смысл только в том случае, если вам нужно собрать объект из некоторых данных, которые требуют шага после инициализации (т.е. после того, как все данные собраны - сделайте что-нибудь с этим). Вместо этого в 99% случаев строители просто используются для инициализации членов класса.
В таких случаях гораздо лучше просто объявить
withXyz(...)
установщики типов внутри класса и заставить их возвращать ссылку на себя.Учти это:
Теперь у нас есть аккуратный отдельный класс, который управляет собственной инициализацией и выполняет почти ту же работу, что и конструктор, за исключением того, что он гораздо более элегантен.
источник
Другое преимущество компоновщика состоит в том, что если у вас есть Фабрика, в вашем коде все еще есть некоторая связь, потому что для того, чтобы Фабрика работала, она должна знать все объекты, которые она может создать . Если вы добавите еще один объект, который может быть создан, вам придется изменить класс фабрики, чтобы включить его. Это происходит и в абстрактной фабрике.
С другой стороны, для строителя вам просто нужно создать нового бетоностроителя для этого нового класса. Класс Director останется прежним, потому что он получает конструктор в конструкторе.
Также есть много ароматов застройщика. Kamikaze Mercenary`s дает еще один.
источник
источник
Основываясь на предыдущих ответах (каламбур), отличным примером из реальной жизни является встроенная поддержка Groovy
Builders
.MarkupBuilder
StreamingMarkupBuilder
SwingXBuilder
См. Builders в Groovy документации
источник
Я использовал builder в домашней библиотеке сообщений. Ядро библиотеки получало данные из сети, собирая их с помощью экземпляра Builder, а затем, как только Builder решил, что у него есть все необходимое для создания экземпляра Message, Builder.GetMessage () создавал экземпляр сообщения с использованием данных, собранных из провод.
источник
Посмотрите InnerBuilder, плагин IntelliJ IDEA, который добавляет действие «Строитель» в меню «Создать» (Alt + Insert), которое генерирует внутренний класс построителя, как описано в разделе «Эффективная Java».
https://github.com/analytically/innerbuilder
источник
Когда я захотел использовать стандартный XMLGregorianCalendar для своего XML для сортировки объекта DateTime в Java, я услышал много комментариев о том, насколько тяжелым и громоздким было его использование. Я пытался контролировать поля XML в структурах xs: datetime для управления часовым поясом, миллисекундами и т. Д.
Поэтому я разработал утилиту для создания XMLGregorian календаря из GregorianCalendar или java.util.Date.
Из-за того, где я работаю, мне не разрешается делиться этим в сети без юридического, но вот пример того, как клиент использует это. Он абстрагирует детали и фильтрует некоторые реализации XMLGregorianCalendar, которые менее используются для xs: datetime.
Конечно, этот шаблон является скорее фильтром, так как он устанавливает поля в xmlCalendar как неопределенные, поэтому они исключаются, он все равно «строит» его. Я легко добавил другие параметры в конструктор для создания структуры xs: date и xs: time, а также для управления смещениями часового пояса при необходимости.
Если вы когда-либо видели код, который создает и использует XMLGregorianCalendar, вы бы увидели, как это облегчает манипулирование.
источник
Отличным примером из реальной жизни является использование при модульном тестировании ваших классов. Вы используете сборщики sut (System Under Test).
Пример:
Учебный класс:
Тестовое задание:
Сул Строитель:
источник
CustomAuthenticationService
класс?