views:

360

answers:

6

I've read about it, I understand it's basic function--I'd like to know an example of a common, real-life use for this pattern.

For reference, I work mostly with business applications, web and windows, using the Microsoft stack.

+1  A: 

EDIT: You will see in my comments that I may have rushed into answering this question, and confused myself in the process. I will go ahead and edit this to work with the Abstract Factory, as I think I originally intended, but please note that this is mainly for reference, not necessarily as a response to the original question.

The most common example I've seen described deals with how GUI components are built.

For example, if you were designing a form for your application, whose GUI components could take on multiple representations (perhaps based on which platform you were running on), you would design an abstract factory to handle the creation of those components.

In order to add new controls to the form, the code might look something like this:

public MyForm ()
{
    GuiFactory  factory = new Win32Factory ();
    Button      btn = factory.CreateButton ();

    btn.Text = "Go!"
    btn.Location = new Point (15, 50);

    this.Controls.Add (btn);
}

This satisfies the Abstract Factory pattern because you can create different instances of the factory object to create different representations of your created objects without changing the client code (this is a rudimentary example, but I think normally you wouldn't create the Win32Factory using new, it would be acquired via some other abstraction).

ph0enix
I was under the impression that the builder encapsulates the building, so the actual builder would return the button in your example so that MyForm() would call this.Controls.Add( builder.BuildGoButton() ); for example.
Chad Grant
Yeah, the more I think about it, I think I had my wires crossed when I left my response. In thinking of GUI, I was probably in the mindset of an Abstract Factory that would create different representations of Button, depending on which platform you were running on.
ph0enix
A: 

A common example that we used to see all the time was a "sysgen" of an operating system. you had a process that selected all the modules you needed, configured them, and returned a bootable image that had been customized.

Charlie Martin
+5  A: 

Think of an Itinerary builder. There are lots of things you can add to you Itinerary like hotels, rental cars, airline flights and the cardinality of each is 0 to *. Alice might have a car and hotel while Bob might have two flights, no car and three hotels.

It would be very hard to create an concrete factory or even an abstract factory to spit out an Itinerary. What you need is a factory where you can have different steps, certain steps happen, others don't and generally produce very different types of objects as a result of the creation process.

In general, you should start with factory and go to builder only if you need higher grain control over the process.

Also, there is a good description, code examples and UML at Data & Object Factory.

JP Alioto
Agreed! In our software, we implement the builder pattern, but the base object is created as the result of a Factory object, and we add to it the necessary components. My answer was more of a real-world coding example, but +1 for seeing it from a more abstract real-world perspective.
ph0enix
+3  A: 

Key use cases:

  • When the end result is immutable, but doing it all with a constructor would be too complicated
  • When I want to partially build something and reuse that partially built thing, but customize it at the end each time
  • When you start with the factory pattern, but the thing being built by the factory has too many permutations

In summary, builder keeps your constructors simple, yet permits immutability.

You said C#, but here's a trivial Java example:

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World!");
System.out.println(sb.toString());

As opposed to:

String msg = "";
msg += "Hello";
msg += " ";
msg += "World!";
System.out.println(msg);
Chris Dolan
StringBuilder example is pretty much the same in C# too.
LukeH
+1 Maybe the most perfect example. And aside from the system.out.println(...), that would compile, and be correct, in C#.
SnOrfus
A: 

One use case that I've encountered is when having multiple data sources. The particular case involved a cache and a database. The majority of the data was pulled from cache, or not. The second loader looked at the data to see whether or not it was loaded from the cache. It would query the database to finish populating the data.

Greg Ogle
A: 

Sometimes it can be helpful to think of non-software related example of design patterns in order to understand them.

I have a system I am working on now that uses a builder to create an order. The order is a class composed of several other classes. My builder creates and validates the associated classes, and if all are valid it then creates an instance of the order class. This way I can be sure that I never have an instance of an order that is missing data.

Gary.Ray