Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Java Tip 50: On the Parameter Constants pattern

Combine nested interfaces and class constants for flexible design and easy access to constants

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 2 of 2

Now that we have this design, are there additional benefits? If the set of constants evolves to become more widely applicable than its parent class it becomes, in essence, an abstraction. It is independent of the original class, which makes things easier on you. Having already separated the two, you are free to widely implement the decoupled constants' interface. An example of this can be found in the SwingConstants interface included in SwingSet.

Parameter Constant pattern

You may be uncomfortable with an interface like CalendarConstants, where the abstraction of the constants truly depends on a single parent class. There is a solution that keeps the interface but uses nested classes to re-encapsulate the constants in the parent class. Let's call this the Parameter Constant pattern and name the interface Parameters. Returning to our Calendar example, this solution encapsulates the constant interface using a top-level nested interface:

  public abstract class Calendar implements Calendar.Parameters {
    public interface Parameters {
      // Fields in interface are implicitly public, static, and final
      int SUNDAY = 1;
      int MONDAY = 2;
      // and so on
      int JANUARY = 0;
      int FEBRUARY = 1;
      // and so on
    }
    // constructors, methods, and fields follow
  }


At first glance, this nesting may seem strange or non-intuitive, but once you see the idea embodied in the code, it makes sense. Other classes can implement Calendar.Parameters or refer to constants directly such as Calendar.SUNDAY, just as before. This nesting solution has the advantage of placing the interface definition properly within its containing class, the advantage of proper containment. Namespace is not polluted with an unnecessarily top-level interface like CalendarConstants. A good candidate for the Parameter Constant pattern is the ScrollPaneConstants interface and its parent class JScrollPane; both are included in JFC's Swing.

Prototype Constant pattern

If you define class prototypes that are constant in the class itself, you can use a similar approach, which we will call the Prototype Constant pattern. Java uses prototypes with java.awt.Color and java.util.Locale. If you could redesign Java's Color class to use the Prototype Constant pattern, you might do the following:

  public Color implements Color.Prototypes {
    public interface Prototypes {
      // Sorry but JavaSoft did not follow uppercase naming convention.
      Color white = new Color(255, 255, 255);
      Color lightGray = new Color(192, 192, 192);
      // and so on
    }
    // constructors, methods, and fields follow
  }


The final concern is whether our approach can accommodate type safety. The constants in Prototype Constant pattern are, by nature, type safe. We can make our Parameter Constant pattern type safe as well while preserving the interface approach. We build upon our pattern with the insights provided by Philip Bishop in Java Tip 27: " Type safe constants in C++ and Java" in JavaWorld. The following is a simple example that does just that, enforcing type safety for the weekday constants of Calendar by introducing an inner class within our Parameters inner interface:

  public class Calendar implements Calendar.Parameters {
    public interface Parameters {
      WeekDay SUNDAY = new WeekDay(0);
      WeekDay MONDAY = new WeekDay(1);
      WeekDay TUESDAY = new WeekDay(2);
      // and so on...
      final class WeekDay { // final for type safety
        // accessible in containing class Calendar
        private final int weekday;
        // private constructor for type safety but accessible in both
        // containers: Parameters & Calendar
        private WeekDay( int i ) {
          weekday = i;
        }
      }
    }
    // example method signature where parameter is type safe
    public void setWeekday( Parameters.WeekDay weekday ) {
      // method implementation
    }
    // Calendar constructors, methods, and fields follow
  }


By making the type safe class WeekDay an inner class within our nested interface Parameters, we add type safety to our earlier accomplishments of proper containment, uncluttered namespace, and easy access constants.

Note that the javadoc utility shipped with JDK 1.1 has trouble with inner classes, but the good news is that javadoc with JDK 1.2 corrects the problem. You can download and use just the javadoc from JDK 1.2 Beta 2 (or later) even though your development platform remains JDK 1.1.

Conclusion

Like any other design technique, use these patterns with good judgement. If a class merely has one parameter with two or three associated constants, it may not be worthwhile to apply the Parameter Constant pattern. Recall that you can inherit multiple interfaces in either client classes or sub-interfaces. The inheritance features combined with the patterns we have developed here leaves you with tremendous flexibility to design your class constants for greatest convenience while keeping them where they belong.

About the author

Jon Steelman has been a software consultant for 10 years. Since early 1996, his passion in programming languages has been Java. His interests also include design patterns and object-oriented analysis and design. He was the first person to become a Sun Certified Java Programmer when Sun started the program in late '96. Jon is a Georgia Tech graduate in electrical engineering and lives in Atlanta.
  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (3)
Login
Forgot your account info?

waste of timeBy Anonymous on September 29, 2009, 10:49 amSorry, but did the author test the code provided? Obviously NOT. First of all it doesn't compile. Secondly, if it did compile, it wouldn't work anyway. SUNDAY, MONDAY...

Reply | Read entire comment

great article but some stuff does not work anymore in 2009?By Anonymous on August 30, 2009, 6:29 amI was trying your second example (Calendar implements Calendar.Parameters), but in Java 5.0 I get: "Cycle detected: the type Foo cannot extend/implement itself or...

Reply | Read entire comment

Great articleBy Anonymous on October 19, 2008, 7:39 amHi! As a Delphi programmer, I really missed its set definition. This is however a great substitute I was looking for. I hated having function parameters declared...

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources
  • Inner Classes Specification
    http://www.javasoft.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html
  • For a review of how to group together constants in an interface and implement the interface in a class, see John D. Mitchell's "Java Tip 5Java constants" http://www.javaworld.com/javaworld/javatips/jw-javatip5.html
  • Read about patterns as they relate to type safe constants in Philip Bishop's "Java Tip 27Type safe constants in C++ and Java" http://www.javaworld.com/javaworld/javatips/jw-javatip27.html