Является ли «StringBuilder» приложением шаблона проектирования Builder?

31

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

У StringBuilderкласса есть слово «строитель» в его имени, но он не имеет ничего общего с телескопическими конструкторами, он просто помогает нам собрать все данные, которые нам нужно передать конструктору неизменного объекта.

Мне кажется, что ответ - это очень четкое «да», но, похоже, есть некоторые разногласия по этой теме, поэтому я надеялся, что кто-то, возможно, сможет это прояснить.

Я отвечал на этот вопрос: программисты SE: законная «реальная работа» в конструкторе? где OP хочет создать (предположительно неизменный) объект, содержащий сложное дерево, и идея шаблона «строителя» всплыла, и во время исследования я нашел этот вопрос и ответ, который, кажется, говорит, что стиль создания объекта «StringBuilder» не применение шаблона «Builder» по причинам, которые мне не ясны: Stackoverflow - StringBuilder и Builder Pattern . (Насколько я могу судить, те, кто отвечал на этот вопрос, не смогли сделать убедительный вывод)

Майк Накис
источник
2
Я нахожу ответ Пола Сасика на этот вопрос переполнения стека совершенно убедительным: StringBuilder - это «обходной путь» для проблемы производительности конкатенации неизменяемых строк, не более того. В лучшем случае StringBuilder "к сожалению, назван". Можно предположить, что StringBuilder может «создавать» веб-страницы, но это конкретное применение общего механизма.
Роберт Харви
3
Ответ Пола Сасика неправильный для Java - я посмотрел на исходный код. StringBuilderкажется, использует базовый символьный массив для представления String и позволяет вам делать такие вещи, как вставки и удаления в любой точке. В конечном счете, я думаю, что StringBuilder - это обходной путь для неизменяемых объектов String, но в остальном мне кажется, что он соответствует замыслу шаблона Builder.
Томас Оуэнс
4
Мне нужно больше думать об этом - это беспокоит меня. Я почти начал писать, почему что-то вроде StringBuilder является версией шаблона Builder, а все остальные ошибались. Но я обнаружил несколько слабых мест, убедил себя, что ошибаюсь, но потом сумел вернуться к своей первой мысли. Если вы посмотрите только на намерение шаблона Builder, легко увидеть, что «StringBuilder - это Builder». Если вы посмотрите на структуру шаблона Builder, это сложнее.
Томас Оуэнс
1
Как бы то ни было, этот ответ о переполнении стека согласуется с моей первоначальной мыслью, что StringBuilder является реализацией компоновщика, и комментарии интересны. Таким образом, вы можете найти обе стороны аргумента. Я одобряю этот вопрос - я не знаю, смогу ли я найти хороший ответ, но это интересный вопрос наверняка. Я буду думать об этом.
Томас Оуэнс
2
Не все паттерны GoF выдерживают испытание временем. Я не говорю , я просто говорю.
Бен

Ответы:

36

A StringBuilderпохож на шаблон Builder, но не очень похож на описание GoF этого шаблона проектирования. Первоначальная точка шаблона дизайна была

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

- от Дизайнерских паттернов Гаммы, Хелма, Джонсона, Влиссида.

(примечание: «сложный» в первую очередь означает «составленный из нескольких частей», не обязательно «сложный» или «сложный»)

«Различные представления» является ключевым здесь. Например, предполагая этот процесс строительства:

interface ArticleBuilder {
  void addTitle(String title);
  void addParagraph(String paragraph);
}

void createArticle(ArticeBuilder articleBuilder) {
  articleBuilder.addTitle("Is String Builder an application of ...");
  articleBuilder.addParagraph("Is the Builder Pattern restricted...");
  articleBuilder.addParagraph("The StringBuilder class ...");
}

мы можем в конечном итоге получить a HtmlDocumentили a TexDocumentили a в MarkdownDocumentзависимости от того, какая конкретная реализация предоставляется:

class HtmlDocumentBuilder implements ArticleBuilder {
  ...
  HtmlDocument getResult();
}

HtmlDocumentBuilder b = new HtmlDocumentBuilder();
createArticle(b);
HtmlDocument dom = b.getResult();

Таким образом, одной из центральных точек шаблона Builder является полиморфизм . Книга Design Patterns сравнивает этот шаблон с абстрактной фабрикой:

Абстрактная Фабрика похожа на Строителя в том, что она также может создавать сложные объекты. Основное отличие состоит в том, что шаблон Builder фокусируется на пошаговом построении сложного объекта. […] Builder возвращает продукт в качестве последнего шага, но что касается абстрактной фабрики, продукт возвращается немедленно.

- от Дизайнерских паттернов Гаммы, Хелма, Джонсона, Влиссида.

Этот пошаговый аспект стал более популярным аспектом шаблона Builder, так что в общем смысле шаблон Builder понимается так:

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

Википедия определяет шаблон следующим образом:

Шаблон Builder - это шаблон проектирования программного обеспечения для создания объектов. В отличии от абстрактной модели фабрики и шаблона метода завода , чье намерение состоит в том, чтобы дать полиморфизм, намерение шаблон строителя, чтобы найти решение телескопической конструкторы анти-паттерн [править] . [...]

У модели строителя есть еще одно преимущество. Он может использоваться для объектов, которые содержат плоские данные (HTML-код, SQL-запрос, сертификат X.509 ...), то есть данные, которые не могут быть легко отредактированы. Данные этого типа не могут быть отредактированы шаг за шагом и должны быть отредактированы сразу. Лучший способ создать такой объект - использовать класс построителя. [нужна цитата]

- из Pattern Builder в Википедии , от разных авторов.

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

Единственное общее свойство StringBuilderразличных интерпретаций шаблона заключается в том, что продукт создается шаг за шагом, а не за один раз. Он не соответствует строгому прочтению определения шаблона проектирования GoF, но, пожалуйста, обратите внимание, что шаблоны проектирования - это гибкие концепции, предназначенные для облегчения коммуникации. Я бы продолжил называть StringBuilderпример паттерна построителя, хотя и нетипичным, - главная причина этой структуры в Java - конкатенация с производительностью при наличии неизменяемых строк, но не какой-то интересный объектно-ориентированный дизайн.

Амон
источник
7
Мне кажется, что создание неизменяемых объектов, по-видимому, является одним из наиболее распространенных применений Builders - я думаю, что это заменило основное использование, как описано в GoF, поэтому согласитесь, что это определенно лучше всего описать как образец шаблона.
Жюль
Согласитесь с использованием при создании неизменяемых графов. Другой сценарий использования для DSL Builder действительно полезен для создания больших графов поддельных данных / ObjectMothers во время тестирования Unit + Integration.
StuartLC