Builder and Fluent
The builder pattern
The builder pattern is a creational pattern, it's a simple pattern and quite natural to implement, in that, we build complex objects from simple objects and we can vary the type of build.The builder pattern is ideal for implementing fluent interfaces, which is, for when you like seperating your logic with a fullstop (period), eg:
var manifold = GetComposite()
.WithSomething()
.AndMoreToConfuseFurther()
.Tangled()
.Build();
Some of the build patterns online and in books are quite complex, often mixing the pattern with
the strategy pattern
and maybe moving a little away from its purity..WithSomething()
.AndMoreToConfuseFurther()
.Tangled()
.Build();
A very nice example, which I'm using for reference, is in the book Adaptive Code (Page 175).
I've created a simple stack data structure with the Top() command indicating to build:
class Stack {
private List stackStorage;
public Stack(){
stackStorage = new List();
}
// invariant item!=null (you've been warned!)
public Stack Push(StackType item) {
stackStorage.Add(item);
return this;
}
public Stack Pop() {
stackStorage.Remove(Top());
return this;
}
// the build
public StackType Top() {
return stackStorage.LastOrDefault();
}
}
The fluent interface is available because of the return this, which
makes the object return itself and then other 'actions' can be called.private List
public Stack(){
stackStorage = new List
}
// invariant item!=null (you've been warned!)
public Stack
stackStorage.Add(item);
return this;
}
public Stack
stackStorage.Remove(Top());
return this;
}
// the build
public StackType Top() {
return stackStorage.LastOrDefault();
}
}
The test code I used is:
static void Main(string[] args) {
Stack stack = new Stack();
int stackResult = stack
.Push(1)
.Push(2)
.Top();
Console.WriteLine("The top of the stack is now {0}", stackResult);
stackResult = stack
.Pop()
.Pop()
.Pop()
.Top();
Console.WriteLine("The top of the stack is now {0}", stackResult);
// alternatively
stack.Push(3).Push(4);
Console.WriteLine("The top of the stack is now {0}", stack.Top());
Console.ReadKey();
}
And the output is:
Stack
int stackResult = stack
.Push(1)
.Push(2)
.Top();
Console.WriteLine("The top of the stack is now {0}", stackResult);
stackResult = stack
.Pop()
.Pop()
.Pop()
.Top();
Console.WriteLine("The top of the stack is now {0}", stackResult);
// alternatively
stack.Push(3).Push(4);
Console.WriteLine("The top of the stack is now {0}", stack.Top());
Console.ReadKey();
}
The top of the stack is now 2
The top of the stack is now 0
The top of the stack is now 4
The top of the stack is now 0
The top of the stack is now 4
The builder pattern (with fluent interfaces) is very good but it's abused by over-zealous programmers.
The method calls need to be meaningful, there's no point in a method name that makes no sense.
Beware of dependencies and ensure that they're internal structure isn't exposed.
Some builders would have to be in a structured order and if the order isn't followed then the exception thrown may not be meaningful.
As the builder pattern can be on the order of the returned 'goods', unit testing every scenario is completely impossible!
Summary
The builder pattern is a well known pattern and (speculation) it's the pattern used by Microsofts EntityFramework
with the ToList() indicating to build.
It's a little open to abuse and should be used with care but it's also very elegant when used with
fluent interfaces, I really like this pattern!