Content deleted Content added
broken page markup |
|||
(43 intermediate revisions by 27 users not shown) | |||
Line 1:
{{WikiProject
{{WikiProject Java|auto=inherit|importance=low}} {{WikiProject Computer science
}}
==Why builders?==
Builders are an OOP pattern to construct complex objects without overloading a constructor. The important part is that you don’t need to call all of the steps to construct. You can call only those steps that are necessary for producing a particular configuration of an object. Also a `director` class helps the builder to construct a specific type of object. I'm missing these concepts in the article. [[User:Theking2|Theking2]] ([[User talk:Theking2|talk]]) 20:52, 25 November 2024 (UTC)
:This is helpful. I've read the wiki and it's still isn't entirely clear to me how or why I would use this. [[User:Jgoure|Jgoure]] ([[User talk:Jgoure|talk]]) 21:49, 7 April 2025 (UTC)
==Builders and immutable objects==
Line 6 ⟶ 14:
A major benefit of builders is that they can be used to create immutable objects without complex constructors. In Java, the builder pattern also simulates named constructor parameters:
<
public final class Pizza {
private final String dough;
Line 37 ⟶ 45:
public Pizza create() {
return new Pizza(
}
}
Line 45 ⟶ 53:
class BuilderExample {
public static void main(String[] args) {
Pizza hawaiian = new
.dough("cross")
.sauce("mild")
Line 52 ⟶ 60:
}
}
</syntaxhighlight>
==Abstract Builder class==
Line 79 ⟶ 87:
This seems to say that the Builder manages "the correct sequence of object creation". Is the client the "Director" or is the builder the "Director"? <small>—The preceding [[Wikipedia:Sign your posts on talk pages|unsigned]] comment was added by [[Special:Contributions/61.14.96.7|61.14.96.7]] ([[User talk:61.14.96.7|talk]]) 07:51, 30 April 2007 (UTC).</small><!-- HagermanBot Auto-Unsigned -->
:According to the UML, the client is the Director. And I believe the word "Director" should be replaced with "Client" for clarity and to avoid confusion since some people tend to think "Director" is a class which is part of the pattern. [[Special:Contributions/186.0.181.64|186.0.181.64]] ([[User talk:186.0.181.64|talk]]) 17:46, 10 April 2023 (UTC)
== Missing the Mark ==
Line 93 ⟶ 103:
Sorry, I don't see the similarity. The only part that is similar is the introductory sentence, which both authors seem to have lifted verbatim from the GoF book, and the secondary concepts, which also, you guessed it, come from the GoF book. [[User:Jdmarshall|Jdmarshall]] ([[User talk:Jdmarshall|talk]]) 11:58, 18 May 2008 (UTC)
I agree that there is little similarity with [http://sourcemaking.com/design_patterns/builder http://sourcemaking.com/design_patterns/builder], but I am concerned that the Pizza example is too similar to the example in Head First Design Patterns.
[[User:AllenDowney|AllenDowney]] ([[User talk:AllenDowney|talk]]) 13:57, 21 April 2011 (UTC)
== Class diagram glitch ==
Line 102 ⟶ 115:
The example given leans more towards abstract factory. As mentioned, Builder is best used for building up Composites. So, Menu Items in menu system, or Genealogy tree of parents and children. Builders can use factories, and often do. This is why the example is confusing. It is attempting to use factories and be a builder at the same time. An improvement to the example would be to have a PizzaFactory, a SoftDrinkFactory and SideOrderFactory. Then, create an OrderBuilder that would build up an order using these factories. I'm not saying that this is the best example, but much clearer than what is there now. A simpler example, like building up a MenuSystem for an application, would be much clearer. <small><span class="autosigned">—Preceding [[Wikipedia:Signatures|unsigned]] comment added by [[User:Hosick|Hosick]] ([[User talk:Hosick|talk]] • [[Special:Contributions/Hosick|contribs]]) 07:44, 17 May 2009 (UTC)</span></small><!-- Template:Unsigned --> <!--Autosigned by SineBot-->
== Abstract functions? ==
Gang of Four says ''not'' to use abstract functions, but instead use empty functions. Normally on a builder pattern you may not want to implement everything, if you set abstract functions then you'll be forced to implement them, even if it was empty. - [[Special:Contributions/114.76.239.105|114.76.239.105]] ([[User talk:114.76.239.105|talk]]) 15:11, 26 December 2010 (UTC)
:This is getting implementation-specific - placeing requirements on the language of implementation which would prevent the pattern from being universally adopted. [[Special:Contributions/15.203.137.74|15.203.137.74]] ([[User talk:15.203.137.74|talk]]) 12:14, 26 November 2014 (UTC)
== Is this the best way of doing this? ==
public class BuilderExample {
public static void main(String[] args) {
Cook cook = new Cook();
PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();
cook.setPizzaBuilder(hawaiianPizzaBuilder);
cook.constructPizza();
Pizza hawaiian = cook.getPizza();
cook.setPizzaBuilder(spicyPizzaBuilder);
cook.constructPizza();
Pizza spicy = cook.getPizza();
}
}
Wouldn't it be better to do something like the following:
public class BuilderExample {
public static void main(String[] args) {
Cook cook = new Cook();
PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();
cook.constructPizza(hawaiianPizzaBuilder);
Pizza hawaiian = hawaiianPizzaBuilder.getPizza();
cook.constructPizza(spicyPizzaBuilder);
Pizza spicy = spicyPizzaBuilder.getPizza();
}
}
The Gang of Four have an interaction diagram that shows that you get the resulting product from the builder. I can't see any reason why you would need a setPizzaBuilder setter - you would just pass the pizzaBuilder in as a parameter. This leads to cleaner code, IMO. - [[User:FluffySquid|FluffySquid]] ([[User talk:FluffySquid|talk]]) 14:11, 17 January 2011 (UTC)
== Two example implementations ==
I'm not sure we need two example implementations. C++ and Java are not radically different in syntax, and there's nothing about the pattern that can't be covered in one. — [[User:Anndelion|<span style="color:#6B8E23;">'''anndelion'''</span>]] [[User_talk:Anndelion|<span style="font-size:125%; vertical-align:text-middle; color:#DAA520"><span class="Unicode">❋</span></span>]] 21:40, 18 April 2011 (UTC)
:Not terribly impressed by the C++ example either - don't expose pointers, use references instead, and the Builder certainly cannot be a singleton. As an example, use more meaningful names - ideally (necessarily) the same as those in other examples to emphasis the relationship between the representations in different languages. [[Special:Contributions/15.203.137.74|15.203.137.74]] ([[User talk:15.203.137.74|talk]]) 12:19, 26 November 2014 (UTC)
== C# implementation ==
In keeping with C# style, shouldn't properties be used instead of java-like setters?
<syntaxhighlight lang = "csharp">
public string Dough {
get {return _dough;}
set {
(do class specific checking...)
_dough = value;
}
}
...
</syntaxhighlight>
== Critics ==
I'm missing the critics section, because the builder pattern is just deeply bad Java, creating a unnecessary complex code and nothing else. Probably those people programming builders didn't understand what a constructor is and what a setter and a getter is. Too bad. It should be forbidden. Furthermore, builder are not real object oriented code, so they also need callback patterns, like in the old days with Fortran and C. But callbacks should nowadays be used only for asymmetric processes, and not for models at all. That's probably why we need (only) one new programming language in the future, prohibiting all those bad implementation patterns. Or, at least a Java compiler who prohibits it. [[Special:Contributions/178.197.234.31|178.197.234.31]] ([[User talk:178.197.234.31|talk]]) 13:36, 6 June 2013 (UTC)
:If somebody comes and says "how am I supposed to do fast parsing without a builder?", you are right in using a builder for loops, like a StringBuilder. But this is a very special case and is only used for parsing Strings. However, for normal objects you should use Externalizable to parse them (newer use Serialisation because it's only 30% Externalizable's speed). So please don't misunderstand me: Builder are okey in a very limited case of String parsing...but then we create the StringBuilder, use it instantly in a loop and afterwards we forget about it. But to use the builder pattern for more than String parsing is just dumb. [[Special:Contributions/178.197.236.254|178.197.236.254]] ([[User talk:178.197.236.254|talk]]) 14:36, 6 June 2013 (UTC)
:Using setters is not a replacement, because setters can cause the object to have an unstable and incomplete form. Builder pattern guarantees that the only object that is modified is the intermediatate object used while creating the final product. When the intermediate object is used up it is discarded. Builder pattern also allows flexible object construction. Suppose you have an object that might need many parameters. <span style="font-size: smaller;" class="autosigned">— Preceding [[Wikipedia:Signatures|unsigned]] comment added by [[Special:Contributions/130.243.188.76|130.243.188.76]] ([[User talk:130.243.188.76|talk]]) 22:50, 13 December 2013 (UTC)</span><!-- Template:Unsigned IP --> <!--Autosigned by SineBot-->
== page confusingly mixes two different unrelated builder patterns in its examples and explanations==
The java example is not the "GOF builder pattern". It's actually the "java builder pattern" (which is really a just a [[Fluent_interface]]). The GOF builder and the "java builder" are significantly different unrelated patterns. The java builder pattern is a wrapper for collecting settings used to eventually construct an object when you've collected enough. And it does it in an easy to read / write "sentence structure" ie: new CarBuilder().wheels(4).paint("blue").type("sedan").interior("leather").makeItSo(); You can use it to with a protected constructor so that all entities that want to build an object have to use the builder to do it. You can also use this java builder pattern in scala to build immutable objects. So that is the java builder pattern. There's no director class for this type of builder. When the page is talking about the builder pattern being a wrapper around a constructor, its talking about the "java / fluent interface" pattern.
The GOF builder pattern is not like this at all. Whereas the java builder pattern is more about convenient sentence like construction, the GOF builder is more about building a complex/compound object using encapsulated builders (builders that no nothing about each other). And it uses a director to coordinate/orchestrate the work allocated to each builder to make the final compound object. So in the car example, you'd have builders that resemble steps in the car assembly with the director representing the "conveyor belt".
with that in mind, I think this page should just refer to the GOF pattern and have an ambiguity link to link the Java builder pattern to the [[Fluent_interface]] page.
<ref>http://stackoverflow.com/questions/26256604/is-the-java-builder-pattern-bloch-really-related-to-the-gof-builder</ref>
[[User:Normana400|Normana400]] ([[User talk:Normana400|talk]]) 18:47, 17 March 2017 (UTC)
{{reflist-talk}}
== Wrong example ==
The pseudocode example does not illustrate the full pattern as described in the GoF book. While we can identify a concrete Builder (CarBuilder) and the product (Car), the Director is somewhat implicit and there is no base Builder class to inherit from.
[[User:Javierieh|Javierieh]] ([[User talk:Javierieh|talk]]) 02:51, 11 November 2014 (UTC)
== "Different representations": What? ==
The preface to the article suggests that the Builder Pattern is basically a solution for creating an object in a programming language where named arguments are not supported, but the member variables have default values that can be overridden, and if they are to be overridden, it should be done upon instantiation. So you create an auxilliary class that collects the arguments to a constructor and then creates the object.
So, in a programming language that does support named arguments, the pattern
disappears:
<syntaxhighlight lang="python">
class Pizza:
def __init__(self,dough='Hand Tossed', sauce='Marinara', topping='Cheese'):
self.dough=dough
self.sauce=sauce
self.topping=topping
# Use the standard dough
p = Pizza(sauce='Garlic Butter', topping='Pepperoni')
</syntaxhighlight>
...But then, the "Definition" section of the article says this:
<blockquote>
The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.
</blockquote>
....which seems to have nothing to do with the purpose of the pattern, which is about specifying numerous optional arguments to a constructor by name. In the above paragraph it sounds like they're talking about being able to create a big endian representation of an integer or a string representation of the same integer with the same constructor class.
None of the code examples show a class that creates objects that offer different representations of the same value. All of the examples show classes that can selectively fill in member variables of the object that is about to be created. An object which only has one representation.
What the point would be of doing this is a separate question. [[Special:Contributions/184.57.129.13|184.57.129.13]] ([[User talk:184.57.129.13|talk]]) 12:20, 8 March 2015 (UTC)
:Keep in mind that here ''representation'' has the [[b:Java Programming/Design Patterns#Terminology|following meaning]]. [[User:Ftiercel|Ftiercel]] ([[User talk:Ftiercel|talk]]) 05:29, 9 March 2015 (UTC)
== Contradictory sections ==
Some sections and examples switch between describing slightly different patterns:
1) Removing telescopic constructions by replacing them with a fluent-style interface. Basically a way of creating named optional parameters. This follows an item given in Effective Java.
2) Allowing clients to create complex objects by building parts separately. The client uses an interface so that different types of objects can be built by creating different concrete builders. This matches the Gang of Four book.
The introduction, C++, Java follow the first pattern.
Definition, Advantages, Disadvantages, Structure, PHP, C# follow the second pattern.
Should we make all the examples consistent, or at least explain the difference? As it is the article is contradictory and confusing. [[Special:Contributions/81.187.215.34|81.187.215.34]] ([[User talk:81.187.215.34|talk]]) 23:42, 22 June 2016 (UTC)
== ICarBuilder examples ==
The examples with ICarBuilder and CarBuilder don't seem quite right because there're no obvious different implementations of ICarBuilder possible. Because they have nearly the same name then the represent the same type instead of a supertype and subtype. If it was say VehicleBuilder and CarBuilder it might make more sense that there could be different concrete implementations.
A less abstract example might be DocumentBuilder with addParagraph, addImage etc methods. Then we could have a PdfDocumentBuilder, WordDocumentBuilder etc implementations. [[Special:Contributions/81.187.215.34|81.187.215.34]] ([[User talk:81.187.215.34|talk]]) 11:23, 10 July 2016 (UTC)
:The current example is no longer about cars. [[User:Dandv|<span style="text-shadow:lightgrey 0.3em 0.3em 0.15em;">Dandv</span>]] 04:33, 6 October 2022 (UTC)
== UML class and sequence diagram ==
I would like to share the following [[Unified Modeling Language|UML]] diagrams I have published on [http://www.w3sdesign.com Design Patterns Open Online Learning]. Your comments are welcomed!
[[File:w3sDesign Builder Design Pattern UML.jpg|frame|none|A sample UML class and sequence diagram for the Builder design pattern.]]
In the above [[Unified Modeling Language|UML]] [[Class diagram|class diagram]],
the <code>Director</code> class doesn't instantiate the <code>ProductA1</code> and <code>ProductB1</code> classes directly.
Instead, the <code>Director</code> refers to the <code>Builder</code> interface to create the objects,
which makes the <code>Director</code> independent of which concrete classes are instantiated (which representation of the complex object is created).
The <code>Builder1</code> class implements the <code>Builder</code> interface by creating and assembling the <code>ProductA1</code> and <code>ProductB1</code> objects
<br>
The [[Unified Modeling Language|UML]] [[Sequence diagram|sequence diagram]] shows the run-time interactions:
The <code>Director</code> object calls <code>buildPartA()</code> on the <code>Builder1</code> object, which creates and assembles the <code>ProductA1</code> object.
Thereafter,
the <code>Director</code> calls <code>BuildPartB()</code> on <code>Builder1</code>, which creates and assembles the <code>ProductB1</code> object. <br>
[[User:Vanderjoe|Vanderjoe]] ([[User talk:Vanderjoe|talk]]) 15:42, 5 August 2017 (UTC)<br>
== The many code examples seem unneeded. ==
If the point of the article is to convey the idea behind the pattern, I think the many, many different language implementations are unnecessary. By display length, the Examples section, with implementations in 9 (!) different languages takes up 80% of the article. This seems quite superfluous, since, unlike, say, an article on a sorting algorithm, nobody is going to copy and paste any of this code into their program.
I'd prefer to either completely remove the Examples section, or only keep, at most, a single language (don't care which).
[[User:Mlouns|Mlouns]] ([[User talk:Mlouns|talk]]) 22:43, 3 June 2019 (UTC)
:This was resolved. Can we delete the section? [[User:Dandv|<span style="text-shadow:lightgrey 0.3em 0.3em 0.15em;">Dandv</span>]] 04:32, 6 October 2022 (UTC)
== Confusing Bicycle example ==
I find the Pizza example given on this Talk page in 2007 ([[#Builders_and_immutable_objects]]) far easier to follow than the [https://en.wikipedia.org/w/index.php?title=Builder_pattern&oldid=1102311912#Examples current Bicycle example]. -- [[User:Dandv|<span style="text-shadow:lightgrey 0.3em 0.3em 0.15em;">Dandv</span>]] 04:30, 6 October 2022 (UTC)
|