My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
WritingQueries  
Example query and recommended style.
Updated Mar 23, 2010 by pascallo...@gmail.com

In most cases, you'll want to extend the AbstractQuery<T> class rather than implement the Query<T> interface. Let's start with the conventional example

class HelloWorld extends AbstractQuery<String> {
  String process() {
    return "Hello, World!";
  }
}

We've define a default visible class named HelloWorld which produces String values. It does nothing else than return a constant greeting.

Let's adapt this code to be a little more polite and mention the user's name when saluting him.

class HelloWorld extends AbstractQuery<String> {
  private final String name;
  HelloWorld(String name) { this.name = name; }

  String process() {
    return "Hello " + name + ".";
  }
}

We've now added a constructor and we can use the value in the process method. Next step is to inject the time.

class HelloWorld extends AbstractQuery<String> {
  private final String name;
  HelloWorld(String name) { this.name = name; }

  @Inject Date now;

  String process() {
    return "Hello " + name + ". It's " + now;
  }
}

Since Date has a no-argument constructor, Guice can inject the current time. We have purposely chosen to make the field default visible to allow the value to be set in tests.

In queries, the recommended style is to lay code following the execution semantics

  1. query construction
  2. injection
  3. processing

Following this pattern improves readability and helps newcomers remember execution ordering.

field vs. method injection

You could also use method injection to get the current time

class HelloWorld extends AbstractQuery<String> {
  private final String name;
  HelloWorld(String name) { this.name = name; }

  private Date now;
  void set(Date now) {
    this.now = now;
  }

  String process() {
    return "Hello " + name + ". It's " + now;
  }
}

However, if you were to add things to inject, you will be obliged to change all the tests using set. Suppose we had the test

@test
public void areYouPolite() {
  HelloWorld query = new HelloWorld("Pascal-Louis");
  query.set(null);
  assertEquals("Hello Pascal-Louis, It's null", query.process());
}

and that we now want to inject one more object

void set(Date now, InjectMe too) { ...

than we would be obliged to change the test because the code will not compile otherwise. If instead you use field injection, the test still compiles. You can now run it and change only those that use InjectMe and most probably now throw a NullPointerException.

At kaChing, we prefer the terser syntax of field injection and have tests to reveal potential problems.


Sign in to add a comment
Powered by Google Project Hosting