Curiously recurring template pattern

From EggeWiki
Revision as of 17:48, 16 April 2007 by Brianegge (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The [CRTP] is a C++ pattern for mix-ins, but I've managed to use variations of it in Java to reduce code duplication. Since you don't have multiple inheritance in Java, you can only have one of these 'mixin' type classes using the CRTP. Also, your limited because Java uses generics and not templates (i.e., new T() won't work). Given that you can't extend String or the primitive wrappers, you end up having to create a lot of boiler plate for a simple delegate. Even if you could extend the basic types, you likely wouldn't want to. Using the CRTP idea, you can move this code into a parent class.

After reading Darren Hobbs post on [Tiny Types] I thought I'd try applying the CTRP to quickly create tiny types.

// a complete type in 4 LOC ... even vi programmers won't object.
public final class FirstName extends TinyType<String> {
  public FirstName(final String s) {
    super(s);
  }
}

public final class Age extends TinyType<Integer> {
  public Age(final Integer integer) {
    super(integer);
  }
}

/**
* @author brianegge
*/
public abstract class TinyType<T> {
  private final T t;

  protected TinyType(T t) {
    this.t = t;
  }

  public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    final TinyType type = (TinyType) o;

    if (t != null ? !t.equals(type.t) : type.t != null) return false;

    return true;
  }

  public int hashCode() {
    return (t != null ? t.hashCode() : 0);
  }

  public T valueOf() {
    return t;
  }

  public String toString() {
    return getClass().getName() + "(" + t.toString() + ")";
  }
}