Reputation: 10332
When comparing to classic properties, what's the big gain of using it ?
I know the repeating of the instance name is gone, but that's all ?
public class PropClass
{
public Object1 object1 { get; set; }
public Object2 object2 { get; set; }
}
PropClass propClass = new PropClass();
propClass.object1 = o1;
propClass.object2 = o2;
public class FluentClass
{
public Object1 object1 { get; private set; }
public Object2 object2 { get; private set; }
public FluentClass SetObject1(Object1 o1)
{
object1 = o1;
return this;
}
public FluentClass SetObject2(Object1 o2)
{
object1 = o2;
return this;
}
}
FluentClass fluentClass = new FluentClass().SetObject1(o1).SetObject1(o2);
Upvotes: 4
Views: 507
Reputation:
Fluent pattern (Builder) will be best benefit when you want to reduce code duplication and reduce dependency between each class. For C# 3.5+, you can create your fluent pattern by creating method extension like LINQ or the following code.
public BaseControl
{
public void RenderControl(HTMLWriter writer) {}
}
public TextBox : BaseControl
{
public string Text { get;set; }
}
public static T TabIndex<T>(this T control, int index) where T : BaseControl {}
After you have the above code, you can use TabIndex to set tab index control that you want like this.
BaseControl control1 = new BaseControl();
control1.TabIndex(1);
// Moreover, you can use this for any devired controls like this
TextBox control2 = new TextBox()
{
Text = "test"
};
// The following method still return TextBox control.
control2.TabIndex(2);
As you see, you can reduce unnecessary code for BaseControl class. But you can plug it alter like I show. This concept works on a lot of classes that have high rate of coupling.
By the way, I like this pattern because it make my code easy to read like the following code.
var pmLogOnName = Html.CreatePopUpMenu("pmLogOnName")
.AddMenuItem("mLogOnName-RememberMe", "Remember UserName", isCheckBox: true, isSelected: true);
Html.CreateTextBox("txtLogOnName", 1)
.BindData(Model, x => x.LogOnName, "showError")
.WaterMark(LogOnView.LogOnName)
.BindMenu(pmLogOnName)
Upvotes: 2
Reputation: 23365
It depends on how it's used. In your example, there's not much point in using a fluent interface.
On the other hand, fluent interface works really well for things like builders, especially when you chain multiple fluent builders together (e.g. car builder / engine builder). I've used Test Data Builders quite extensively and they work really well. You can do the same thing without a fluent interface, but it's not so nice to use.
Furthermore, there is the Domain Specific Language angle that Martin Fowler explains here.
The only problem is that people sometimes go a bit crazy with fluent interfaces and create overly verbose APIs, but that's less of a fluent interface problem and more of an application/implementation problem, in my opinion.
Upvotes: 2
Reputation: 50728
There isn't necessarily a big advantage, in my opinion, or simple classes like you have above (classes with a few properties). It's a different semantic that some developers are comfortable with on one hand. On the other hand, I think it's very advantageous in certain arenas like ASP.NET MVC... I use the Telerik MVC controls which uses a fluent interface and it is very nice to setup the controls with; the MS way requires using collections and anonymous classes, and it's not so convenient to use.
HTH.
Upvotes: 0
Reputation: 1039180
IMHO there's no big gain of setting properties with fluent interface, especially with C# 3.0 class initializers. Fluent interfaces become more interesting when you start chaining methods and operations.
Upvotes: 6