Curiously recurring template pattern: Difference between revisions

From EggeWiki
No edit summary
 
mNo edit summary
Line 21: Line 21:
*/
*/
public abstract class TinyType<T> {
public abstract class TinyType<T> {
  private final T t;
    private final T t;


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


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


    final TinyType type = (TinyType) o;
        final TinyType type = (TinyType) other;


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


     return true;
     // Checkstyle thinks the Cyclomatic Complexity is to high to have this all in one method!
  }
    private boolean equals(final TinyType other) {
        return !(t != null ? !t.equals(other.t) : other.t != null);
    }


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


  public T valueOf() {
    public T getValue() {
    return t;
        return t;
  }
    }


  public String toString() {
    /**
    return getClass().getName() + "(" + t.toString() + ")";
    * @return The name of this type and the value.  I.e., Age(5)
  }
    */
    public String debug() {
        String[] classes = getClass().getName().split("\\.");
        return classes[classes.length - 1] + "(" + t.toString() + ")";
    }
 
    /**
    * @return the toString of type T
    */
    public String toString() {
        return t.toString();
    }
}
}
</pre>
</pre>

Revision as of 22:24, 22 April 2007

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 other) {
        if (this == other) {
            return true;
        }
        if (other == null || getClass() != other.getClass()) {
            return false;
        }

        final TinyType type = (TinyType) other;

        return equals(type);
    }

    // Checkstyle thinks the Cyclomatic Complexity is to high to have this all in one method!
    private boolean equals(final TinyType other) {
        return !(t != null ? !t.equals(other.t) : other.t != null);
    }

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

    public T getValue() {
        return t;
    }

    /**
     * @return The name of this type and the value.  I.e., Age(5)
     */
    public String debug() {
        String[] classes = getClass().getName().split("\\.");
        return classes[classes.length - 1] + "(" + t.toString() + ")";
    }

    /**
     * @return the toString of type T
     */
    public String toString() {
        return t.toString();
    }
}