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.