Fluent Interface vs. Method Chaining vs. DSL

by admin 12. September 2007 21:53

Wo der der Unterschied zwischen "Method Chaining" und einem "Fluent Interface" liegt, ist sicher eine Ermessensfrage. Hier ein Beispiel für Method Chaining:

1 StringBuilder stringBuilder = new StringBuilder(); 2 stringBuilder 3 .Append("Method Chaining -") 4 .Append("die wohl älteste Methode") 5 .AppendLine("der Welt") 6 .AppendLine(":-)");


Ein Fluent Interface liefert hingegen Kontext, nehmen wir diesen Code:

 

1 PlaceOrder 2 .CreateNew(PremiumOrder.With(22).Items) 3 .For.User("MR-T") 4 .InCase( 5 User.IsFriendlyLevel == AboveAverage && 6 User.Age > 18 7 ).Commit()

 

Die Implementierung für obigen Code ist deutlich interessanter aufwändiger. Wenn bis zum Ende durch exerziert, ist nach jedem Methodenauswahl nur eine sinnvolle Menge von Methoden, also Kontext Abhängiges Interface nach außen gelegt. 

 

1 public class PlaceOrder 2 { 3 public static IOrderPrepared CreateNew(OrderDescriber orderDesc){ 4 return GetPreparedOrderBy(orderDesc); 5 } 6 7 public static Order GetPreparedOrderBy(OrderDescriber orderDesc){ 8 Order order = new Order(orderDesc.itemCount); 9 return order.ServiceLevel = orderDesc.ServiceLevel; 10 } 11 12 } 13 14 public class OrderDescriber 15 { 16 public OrderDescriber Items{ 17 get{ 18 AmountType = OrderAmountType.Items; 19 return this; 20 } 21 } 22 23 public OrderAmountType AmountType = OrderAmountType.Boxes; 24 25 public OrderDescriber(int itemCount){...} 26 27 public static OrderDescriber With(itemCount){ 28 return new OrderDescriber(itemCount) 29 } 30 } 31 32 public interface IOrderPrepared{...} 33 ...

 

Der Obige (Pseudo) Code erstellt eine Schnittstelle, die sich per IntelliSense bedienen lässt.

Es lohnt sich wohl nur soviel Arbeit zu investieren, wenn der Kontext schwierig ist und sich so Fehler vermeiden lassen. Interessant es auch die Zeit zu investieren, wenn vorrausichtlich viele Entwickler den Code verwenden werden. Alternativ kann man vereinfachen und den Kontext weitestgehend weglassen, also ein Arsenal möglicher Methoden nach außen legen.

Ein  Fluent Interface ist aus meiner Perspektive auch "Domain Specific Language" für die gilt: je einfacher die nach Außen gelegte Schnittstelle, desto zeitraubender ist die Implementierung.

Wobei die Schnittstelle, das Fluent Interface nur eine Facade für die eigentlichen Domain Objekte sein sollte und nicht die Business Logik komplizierter machen sollte.

Comments are closed

About Oliver

shades-of-orange.com code blog logo I build web applications using ASP.NET and have a passion for javascript. Enjoy MVC 4 and Orchard CMS, and I do TDD whenever I can. I like clean code. Love to spend time with my wife and our children. My profile on Stack Exchange, a network of free, community-driven Q&A sites

About Anton

shades-of-orange.com code blog logo I'm a software developer at teamaton. I code in C# and work with MVC, Orchard, SpecFlow, Coypu and NHibernate. I enjoy beach volleyball, board games and Coke.