Never return Null Arrays – really?

Scott Selikoff recently posted that we should “never return null arrays”. I’m not sure I entirely agree. Both the tone of the article and the comments so far seem to be in agreement, but I am still not so sure.

I’ll skip the terminology issue for the moment, just note that an array in Java is different, in syntax, interface and implementation, from a Collection. Scott’s article seems to discuss Collections rather than arrays.

As far as I am concerned, there is a qualitative distinction between a Collection which exists, but is empty, and a collection which simply does not exist (i.e is null). I’ll grant that in many situations they should result in the same action or output; but not always.

Imagine parsing XML documents. Consider the following three cases:

  <result>
  </result>
  <result>
     <stuff/>
  </result>
  <result>
     <stuff>
       <item id="1"/>
       <item id="2"/>
     </stuff>
  </result>

I suggest that first and second cases are different. It’s relatively easy to imagine that some software should behave differently in the case where the “stuff” block is not present at all, and in the case where it is present, but empty. A simplistic example might be that in the second and third cases a “Stuff” heading is rendered on a web page, but not in the first one.

If that abstract example is not enough to convince, consider the more practical example of an “all you can eat” buffet restaurant (pause for a Homer Simpson “mmm … buffet“). The way many of these places work is that when you arrive you pay a flat fee and receive an empty plate. You may then take that plate to the food and fill it with whatever you like. If you do not have a plate, you have not paid, and so can neither physically nor contractually fill it with food.

In this example the plate represents the collection. The state of having no (null) plate is very different from having an (empty) plate. The restaurant staff would be wise to know the difference.

Just for fun, here’s some java to illustrate:

public class Diner {
  private Wallet wallet;
  private Collection plate;
 
  public Diner() {
    wallet = new Wallet();
  }
 
  public void pay(Cashier cashier) {
    Money fee = wallet.extract(cashier.getFee());
    this.plate = cashier.payForPlate(fee);
  }
 
  public void selectFoodItem(Buffet buffet, Object item) {
    if (buffet.contains(item)) {
      buffet.grab(item, plate);
    }
  }
}
public class Buffet {
  public boolean contains(Object item) {
    return true; // the ultimate buffet :)
  }
 
  public void grab(Object item, Collection plate) {
    if (null == plate) 
      throw new RestaurantException("This is not a soup kitchen! Pay first or hit the road");
    if (plate.size() > 10)
      System.out.println("I see you brought your big plate, Alan");
    plate.add(item);
  }
}

The bottom line is that while the Null Object pattern is a very useful pattern, it should not be used indiscriminately. Just like any pattern, really.

Never return Null Arrays! | Down Home Country Coding With Scott Selikoff and Friends

I look forward to more thought-provoking posts from Scott and Jeanne!

mockito 1.5 and spying on objects

Mockito is a Java Mock objects framework which seems more usable than either of the main contenders (JMock and EasyMock). The project has just released a new version which now allows the attachment of a mock “overlay” to an existing object.

This has been on my “evaluate” stack for months, but (as Harry Pynn pointed out when he “vouched for” me) I tend to be more comfortable with “classic” TDD and don’t usually find much use for Mock Objects.

I have had a quick play with the examples of use on the Mockito site with mixed success. many obvious cases work well, but there are also some gaps in the way it works. For example, consider this small example test:

import static org.mockito.Mockito.spy;
 
public class PlaypenTest extends TestCase {
	public void testMockito() {
		List real = new ArrayList(); 
		real.add("first");
		real.add("second");
		List ml = spy(real);
 
		stub(ml.get(0)).toReturn("huh");
		assertEquals("huh", ml.get(0));
		assertEquals("second", ml.get(1));
	}
}

It works correctly. However, the following idiomatic and functionally similar simplification throws a complicated internal exception in the “spy” method.

import static org.mockito.Mockito.spy;
 
public class PlaypenTest extends TestCase {
	public void testMockito() {
		List real = Arrays.asList(new String[] {"first", "second"});
		List ml = spy(real);
 
		stub(ml.get(0)).toReturn("huh");
		assertEquals("huh", ml.get(0));
		assertEquals("second", ml.get(1));
	}
}

Maybe I’ll get around to using it for something. I’m still not sure.

mockito – Google Code