Chitika

Monday, January 02, 2006

Understanding Fluent Interface

After reading Martin Fowler's post regarding fluent interface, I try to write small trivial implementations to understand the concept. Here are the common interfaces of Customer, Order & OrderLine classes, as required by Martin's "makeNormal" method:

Customer
  +addOrder(Order): void

Order
  +addLine(OrderLine): void
  +setRush(boolean): void

OrderLine
  +OrderLine(int, Product)
  +setSkippable(boolean): void

It's quite standard for OO design. Looking at Martin's "makeFluent" method, we need the following interfaces, which I've added some trivial implementations to help understanding the concept:

Customer
+newOrder(): Order
{
  Order o = new Order ();
  this.addOrder (o);
  return o;
}

Order
+with(qty, productId): OrderLine
{
  Product p = Product.find (productId);
  OrderLine line = new OrderLine (qty, p);
  this.addLine (line);
  line.setOrder (this);
  return line;
}
+priorityRush(): Order
{
  this.setRush (true);
  return this;
}

OrderLine
+with(qty, productId): OrderLine
  //note: return the last order added, instead of this
{
  Product p = Product.find (productId);
  OrderLine line = new OrderLine (qty, p);
  this.order.addLine (line);
  line.setOrder (this.order);
  return line;
}
+setOrder(order): void
{
  this.order = order;
}
+skippable(): OrderLine
{
  this.setSkippable (true);
  return this;
}
+priorityRush(): Order
{
  this.order.setRush (true);
  return this.order;
}

Looking at the above sample implementation codes, we need to design additional interfaces to help the client usage be more fluent. Things I've noted:
1. Fluent API can only be applicable for highly used API, otherwise the investment of designing the API may not be as effective as intended. Thus, not all API can be made fluent.
2. Fluent API may be good for "feature-envy" code smells. Feature-envy is when a "client" method calls methods on another class three or more times.
3. Fluent API is suitable for frameworks, e.g. Hibernate, libraries, e.g. Jakarta Commons, or related OO classes (as in Martin's example). But, the timing for designing Fluent API for OO classes is still a big question. If we design it too early, there may be useless API (or the API is not fluent enough). If we design it too late, the ROI may not be as expected.

The pendulum is still swinging.. :D
I hope I can think this through the week, and let you guys know what I think..

No comments:

Post a Comment