Atom Feed SITE FEED   ADD TO GOOGLE READER

Returning boolean isn't always that helpful

In complex systems, transparency can sometimes help. In my fake pizzastore application, I've got an API that's used to control whether the Place Order! button is enabled or disabled:
  public boolean isOrderValid(PizzaOrder pizzaOrder) {
if (!geography.isAcceptableAddress(pizzaOrder.getAddress())) {
return false;
}

if (!deliveryRules.isLargeEnoughOrder(pizzaOrder)) {
return false;
}

List<Store> storesInRange = storesRegistry.getStoresWithinRange(
pizzaOrder.getAddress(), MAXIMUM_DELIVERY_RADIUS);
if (storesInRange.isEmpty()) {
return false;
}

return true;
}
It works well. But sometimes I'll get a bug report complaining that the button is disabled when it shouldn't be. The problem isn't that the button is disabled, it's that the user doesn't know why the button is disabled. The fix is easy:
  public List<String> getReasonsWhyOrderIsInvalid(PizzaOrder pizzaOrder) {
List<String> reasons = new ArrayList<String>();

if (!geography.isAcceptableAddress(pizzaOrder.getAddress())) {
reasons.add("Unacceptable address");
}

if (!deliveryRules.isLargeEnoughOrder(pizzaOrder)) {
reasons.add("Order is not large enough");
}

List<Store> storesInRange = storesRegistry.getStoresWithinRange(
pizzaOrder.getAddress(), MAXIMUM_DELIVERY_RADIUS);
if (storesInRange.isEmpty()) {
reasons.add("No stores in range of " + pizzaOrder.getAddress());
}

return reasons;
}

public boolean isOrderValid(PizzaOrder pizzaOrder) {
return getReasonsWhyOrderIsInvalid(pizzaOrder).isEmpty();
}
I can use the list of warnings as a tooltip on the disabled button, or use more sophisticated reporting as necessary. This works really nicely, and it keeps the end users informed.

Applying this technique elsewhere
There's lots of complex rulesets throughout the code. On one screen we show a tab with navigation data for deliveries in progress. That tab is displayed only if the navigation feature is configured, the user has sufficient credentials, and if GPS reports are being received.

By displaying the reasons why the navigation tab is not shown on an admin page, I can diagnose problems without a debugger. Reasons are more helpful than booleans because they guide me in my investigation. This approach works nicely in webapps, where it's easy to include extra admin pages.

In my app, reasons pages provide every detail on why the application is behaving the way it is - transparency is great!