C# Corner

The Builder Pattern in .NET

How to separate complex object construction from its representation using the Builder design pattern in C#.

The Builder Pattern is a common software design pattern that's used to encapsulate the construction logic for an object. This pattern is often used when the construction process of an object is complex. It's also well suited for constructing multiple representations of the same class. First, I'll go over the basics of the pattern, and then I'll provide an example to crystallize the concepts.

Core Concepts
The Builder Pattern is comprised of four components: a builder interface, a concrete builder, a director and a product. The builder interface defines a template for the steps to construct the product. The concrete builder implements the builder interface and provides an interface for getting the product. The director actually constructs the object through the builder interface. The product is the end object that's constructed.

Now that you understand the concepts of the pattern, I'll go over a full implementation of the pattern. My simple example encapsulates the process of brewing a beer. The first step is to define the Beer class, which is the product that will be built. The Beer class is a simplified representation of a beer that includes a label, volume, price and potency. I also added a ToString method override to concisely display the full contents of the object. See Listing 1 for the Beer class source code.

Next, I define the IBeerBuilder interface that specifies the necessary steps of constructing a beer object. I've also added a GetBeer method that returns the beer object at any time of the construction process. See Listing 2 for the full IBeerBuilder interface source code.

Now that I've defined the builder interface and the product, a concrete builder class that implements the IBeerBuilder interface is needed. In this case, I've created two beer builders, one for an amber ale (Listing 3) and one for a stout (Listing 4).

Fully Constructed Object
The final piece is to define a director class that will take a given IBeerBuilder interface and use it to execute the necessary steps to brew the beer. The BrewMaster class includes three methods: SetBeerBuilder, GetBeer and BrewBeer. The SetBeerBuilder class allows the consumer to set the IBeerBuilder interface to build the needed beer. The BrewBeer method executes the steps in order to fully brew the beer using the set IBeerBuilder, and the GetBeer method returns the fully constructed Beer object. See Listing 5 for the full BrewMaster director class source code.

Finally, to fully test the Builder Pattern implementation: First, create a new BrewMaster instance; then call the SetBeerBuilder method with a concrete IBeerBuilder object instance. Next, call the BrewBeer method on the BrewMaster instance. Lastly, call the GetBeer method on the BrewMaster to get the fully constructed Beer instance. The same BrewMaster instance can be used to create multiple Beer object representations as represented in Listing 6 and Figure 1.


[Click on image for larger view.]
Figure 1. Finished Builder Pattern Demo App

As you can see, the true strength of the Builder Pattern is that it lets you break up the construction of a complex object. Not only that, it also allows you to hide the construction process from the consumer, thus allowing for additional representations of the product to be added with ease. The pattern also encourages separation of concerns and promotes application extensibility.

About the Author

Eric Vogel is a Sr. Software Developer at Kunz, Leigh, & Associates in Okemos, MI. He is the president of the Greater Lansing User Group for .NET. Eric enjoys learning about software architecture and craftsmanship, and is always looking for ways to create more robust and testable applications. Contact him at vogelvision@gmail.com.

comments powered by Disqus

Reader Comments:

Mon, Sep 17, 2012 Mishelle

I can see a use for this. If BrewBeer() is not just a fixed list of steps, but it needs to coordinate with other dependencies, then you might want to isolate those dependencies. Suppose BrewBeer() needs to gather ingredients. If I create a new mohito beer that needs mint, I don't want to add a mint dependency to my base Beer class.

Thu, Aug 16, 2012 Jenda

In 99 out of 100 cases using a simple delegate/method reference/lambda would be both simpler and more efficient. The director stores a Func, you set this using a lambda or method reference and the director may construct the object any time it needs. No need for a specific builder interface and tens of builder classes. Of course you can't go crazy defining ten methods you have the director has to call in the right order to construct the object then.

Thu, Aug 9, 2012

Might as well add a stringcollection setting of class names (or search a dir for the interface) that get created via Type.GetType & Activator.CreateInstance. This will remove the dependencies of the concrete class types. Inheritance is so 80's, wasteful and dependent (+ only 1 in CLR).

Sun, Aug 5, 2012 Joshua USA

Basically the interface acts as a requirement template for snap-in modules used by the director via inversion of control. All we're really doing here is subtyping the builder through different interface implementations. I think that those of us who are a little leary of someday seeing computer classes immortalize 'patterns' like conic sections in math would prefer to focus on the execution path rather than the object heirarchy, the latter the programmer's mind will sort out easily enough. If the different beers were being created asynchronously then focusing on the pattern heirarchy would seem to deliver more bang for the buck.

Fri, Aug 3, 2012 martin

Nice article. It would be nice to clean up the using references (System.Collections.Generic, System.Linq, etc). Remove Unused Usings is your friend

Fri, Aug 3, 2012 Daniel Maxwell Woodbridge, VA

For people like me, not having a formal education in computer science or software development, finding my path more and more in the field of application development, I appreciate this article and the understanding it provides to better improve the architecture of my code. Thank you.

Thu, Aug 2, 2012 George Jordanov

As any other pattern "The Builder Pattern in .NET" is a pattern. What is a pattern? Anything (if it is a think at all) that some could talk about (or have in mind by any means) but cannot precisely describe. According to Steve McConnell (and all human experience so far) in software building approximate solutions do not work. Sorry to see so pointless publication in this magazine.

Wed, Aug 1, 2012 LSN

hi Eric, I am not sure I understand your response to PHVOS. Why should the client *have* to call BrewBeer and then GetBeer ? I think he was asking why BrewMaster.GetBeer isn't more like this: If Beer not already brewed/available, brew beer. Then return beer. This way the client calling BrewBeer itself is optional. Yes, there could be a time lag between operations, and the client is going to have to wait longer if it calls GetBeer without "calling ahead" to make sure that the beer is already available . But that matches reality, doesn't it? >L

Wed, Jul 18, 2012 Eric Vogel Okemos

Fred - The main advantage of using the builder pattern over inheritance with abstract method overrides for each derived product class is that the product's construction process is hidden from the consumer of the code via the Director class. This is a great thing if you are finding that you have to pass many parameters to a constructor, constructing a composite object, or have a well defined but expensive construction process. It all depends on the complexity of the object's construction. PHVOS - In the builder pattern the product is returned as the final step. This allows for the product to be constructed in a piecemeal manner if needed. This is great if for example the Director class needs to wait for input before proceeding to the next Builder class's construction step. In contrast in the factory and abstract factory patterns the product is immediately returned.

Wed, Jul 18, 2012 Fred

Hi Eric, out of curiosity, what is the advantage to using this approach versus regular inheritance. Amber Ale "is a" beer and stout "is a" beer. Couldn't the same thing be accomplished by deriving from an abstract Beer class and making the methods abstract? I've always been under the impression that interfaces are necessary when providing expected functionality to unrelated classes. But in this example the classes are related thus it lends itself to an inheritance architecture. Thanks!

Tue, Jul 17, 2012 phvos

Why does the director needs to call BrewBeer and GetBeer. Is this not overdone? Why not only use one method which internally calls the other. I do not want the client/caller to now he has to call BrewBeer and then GetBeer...

Add Your Comments Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Comment:
Please type the letters/numbers you see above

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.