Ary Borenszweig

Ary Borenszweig

The requestor pattern: avoid looping twice

4 min
Mar 26 2008
testing, coding
4 min
Mar 26 2008

In my quest for making every piece of code testable, I run across the requestor pattern. You won't find it doing a Google search. I first saw it in many places in JDT's source code. The idea is separating an extraction of information (a processor) from it's actual processing (a requestor).

For example, JDT has a class named SourceElementParser that parses a source file and notifies it's top-level memebers, like classes, methods and fields. This class only does the parsing job and notifies the result to an ISourceElementRequestor, which has methods like enterType, exitType, acceptField, etc. In this way, the extraction of the top-level members is separated from what is actually done with that information, allowing testabilty of the processor by mocking the requestor.

Also, as the top-level members are discovered, they are notified to the requestor. Another possible implementation could be that the job done by SourceElementParser would return a tree structure representing the top-level members. This tree structure could then be processed by any class wishing to use it. The problem with this approach is that you loop twice: first for building the structure, then for processing it.

A second example is a processing REST requests. Imagine a simple contacts service, where you can retrieve all the contacts, create, edit, or delete one. The URLs could be ".../all", ".../create?id=...&name=...", etc. The requestor pattern solution is the following: a class that parses an URL and notifies interesting, object oriented information to a requestor.

public class RestProcessor {
  public void process(String url, IRestRequestor requestor) {
    if (".../all".equals(url)) {
      requestor.getAllContacts();
    }
    // ...
  }
}

public interface IRestRequestor {

  void getAllContacts();

  void createContact(String name);

  void editContact(int id, String name);

  void deleteContact(int id);

}

Yet another example: treemaps. Given an array of numbers, tell in which rectangle to position them. The class responsible for doing this could return an array of rectangles, but if the numbers to process are a lot, then two loops will happen: one for the calculation of the rectangles, the second for the actual use of them. Using the requestor pattern is straight forward:

public class TreemapProcessor {

  public void doTreemap(double[] numbers,
    double width, double height,
    ITreemapRequestor requestor)
      // ...
  }

}

public interface ITreemapRequestor {

  void position(int numberIndex,
    double left, double top,
    double width, double height);

}