Typesafe Enum: Using enum in J2SE 5.0

Originally posted 12-Nov-2003

Java version 5.0 introduces many dramatic new language features. This article discusses the new enum facility.

Enumerated Constants

A frequent pattern in Java is the use of enumerated constants–that is, a set of static final variables that can be semantically grouped. For example, a student grading system needs to be able to capture each of five possible letter grades–A, B, C, D, or F. One standard idiom for implementing this list of constants in Java:

public class Student {
   public static final char GRADE_A = 'A';
   public static final char GRADE_B = 'B';
   public static final char GRADE_C = 'C';
   public static final char GRADE_D = 'D';
   public static final char GRADE_F = 'F';
   // ...
   public void addGrade(char grade) {
   	// ...
   }
}

Client code:

new Student().addGrade(Student.GRADE_B);

There are a few problems. First, the declaration code is redundant–public static final this, public static final that, etc. Secondly, multiple classes may have use for the constant, but not for the class in which they are defined. Third, and most problematic, is that the constants are not type-safe: Nothing prohibits a client from passing in the character 'Z' to the addGrade method.

The second problem, where the constants are defined, is often solved by use of the Constant Interface pattern. A Constant Interface takes advantage of the fact that you can declare static constants in a Java interface. Classes that need to use the constants simply implement the interface.

However, Joshua Bloch, in his book Effective Java, describes Constant Interface as an anti-pattern. It violates good coding standards by exposing an implementation detail–where constants are defined–to client code. A downside of doing so is that you cannot change the constant interface without impacting the client.

Typesafe Enum

As an alternative, Bloch and I (see Essential Java Style) have promoted the Typesafe Enum pattern.

Using Typesafe Enum, you create a new class whose constructor is private.
You create static constants of the class to represent the only valid
instances. This restricts clients to only use the valid instances.

Building a Typesafe Enum class is not a huge task, but nor is it trivial. Getting nuances such as serialization and synchronization capability working right can be difficult. Thus Bloch was the main promoter of building a correct implementation of Typesafe Enum directly into the Java language.

The enum Type

J2SE 5.0 allows you to declare a type as an enum type. In its simplest form, an enum type requires you to specify a type name and the names of its valid instances. The declaration is about as succinct as possible:

enum Grade { A, B, C, D, F };

That’s it. An enum can be a top-level type, or it can be declared within another class. You use the enum instances just as you would refer to a static variable:

Grade grade = Grade.C;

The addGrade method declaration changes to:

public void addGrade(Grade grade)

It is no longer possible to pass an invalid parameter! The only valid Grade instances are defined by the Grade enum itself. (It is also not possible to subclass the Grade enum, one technique which would have provided a workaround to the safety mechanism.)

Switching on enum Values

The switch statement has been enhanced to support enum types:

switch (grade) {
   case A: print("great"); break;
   case B: print("good"); break;
   case C: print("ok"); break;
   case D: print("eh"); break;
   case F: print("loser"); break;
}

However, as per good OO programming guidelines, you should avoid the use of switch statements. One way would be to provide a mechanism in the Grade type itself to return an appropriate message. An enum type can have fields, constructors, and methods, just like a class type. Here’s how you could associate a message with each Grade instance:

enum Grade {
   A("great"),
   B("good"),
   C("ok"),
   D("eh"),
   F("loser");

   private String message;

   Grade(String message) {
      this.message = message;
   }

   String getMessage() {
      return message;
   }
}

An example of printing the message:

Grade grade = Grade.C;
System.out.println(grade.getMessage());

Additional Fields

There are three useful methods that you can use with enum types. First, the static method values() returns a list of all the enum constants. The following code uses the J2SE 5.0 for-each loop to iterate the list of Grade instances and print each:

for (Grade grade: Grade.values())
   System.out.println(grade);

You might also find the enum public instance methods ordinal() and name() useful. The name() method returns the name of the instance as specified in the enum declaration. For example, the name for Grade.C is “C”. The ordinal() method returns an int representing the position of the Grade instance in the enum list. Thus the ordinal of Grade.A is 0, the ordinal of Grade.B is 1, and so on. Sun recommends you not depend on the value of the ordinal.

Since each enum has an associated name, the Enum class provides a way for you to get the appropriate enum instance given a String.

Grade grade = Grade.valueOf("F");

You’ll get an IllegalArgumentException if you pass a String that doesn’t match any of the enum names.

Polymorphic Enums

The follow-up article, Polymorphic Enums in J2SE 5.0 (Tiger), discusses how you can use polymorphism to create distinct behavior for any enum constant.

Small Methods: Nine Benefits of Making Your Methods Shorter

I’ve espoused, on many occasions, making your methods short. The pattern Composed Method, defined by Kent Beck in Smalltalk Best Practice Patterns, says that methods should do things only at one level of abstraction. Methods should be short; a good size for Smalltalk methods is one to a half-dozen lines. That translates to about one to twelve lines (not counting braces!) for Java methods.

I recently engaged in a discussion at JavaRanch where someone thought “20 to 25 lines” was too short. After being taken aback, my response was that there are many reasons that your average method size should be considerably smaller. Here are nine benefits to short methods:

  1. Maintenance costs. The longer a method, the more it will take you to figure out what it does, and where your modifications need to go. With shorter methods, you can quickly pinpoint where a change needs to go (particularly if you are coding using test-driven development).
  2. Code readability. After the initial learning curve, smaller methods make it far easier to understand what a class does. They can also make it easier to follow code by eliminating the need for scrolling.
  3. Reuse potential. If you break down methods into smaller components, you can start to recognize common abstractions in your code. You can minimize the overall amount of code dramatically by reusing these common methods.
  4. Subclassing potential. The longer a method is, the more difficult it will be to create effective subclasses that use the method.
  5. Naming. It’s easier to come up with appropriate names for smaller methods that do one thing.
  6. Performance profiling. If you have performance issues, a system with composed methods makes it easier to spot the performance bottlenecks.
  7. Flexibility. Smaller methods make it easier to refactor (and to recognize design flaws, such as feature envy).
  8. Coding quality. It’s easier to spot dumb mistakes if you break larger methods into smaller ones.
  9. Comment minimization. While comments can be valuable, most are unnecessary and can be eliminated by prudent renaming and restructuring. Comments that restate what the code says are unnecessary.

You should get the idea that most of the benefits are about improving the design of your system. Breaking methods up into smaller ones obviously leads to lots of smaller methods. You will find that not all of those methods should remain in the same class in which the original method was coded. The small methods will almost always point out to you that you are violating the basic rule of class design: the Single Responsibility Principle (SRP).

The SRP states that a class should have only one reason to change. Put another way, a class should do one thing and one thing only. A class to present a user interface (UI) should do just that. It shouldn’t act as a controller; it shouldn’t retrieve data; it shouldn’t open files; it shouldn’t contain calculations or business logic. A UI class should interact with other small classes that do each of those things separately.

Break a class into small methods, and you will usually find all sorts of violations of the SRP.

Initially, you may find it more difficult to work with code with lots of methods. There is certainly a learning curve associated with doing so. You will find that the smart navigational features of your IDE (for example, Eclipse) can go a long way toward helping you understand how all the little methods fit together. In short time, you will find that well-composed code imparts much greater clarity to your system.

One oft-repeated resistance to short methods is that it can degrade performance in your system. Indeed, method calls are usually fairly expensive operations. However, you rarely create performance problems with more methods. Poor performance can usually be attributed to other factors, such as IO operations, network latency, poor choice of algorithm, and other inefficient uses of resources.

Even if additional method calls do noticeably impact performance (performance is not an issue until someone recognizes it as one), it’s very easy to inline methods. The rule of performance is always: make it run, make it right (e.g. small methods), make it fast (optimize).

While it’s difficult to do, you can go too far and create too many methods. Make sure each method has a valid reason for existing; otherwise inline it. A method is useless if the name of the method and the body of the method say exactly the same thing.

There are exceptions to every rule. There will always be the need for the rare method larger than 20 lines. One way to look at things, however, is to look at smaller methods as a goal to strive for, not a hard number. Instead of debating whether 25 lines, 12 lines or 200 lines is acceptable, see what you can do to reduce method length in code that you would’ve otherwise not touched. You’ll be surprised at how much code you can eliminate.

Few people promote pushing in the other direction. Increasing the average method size represents sheer carelessness or laziness. Take the time and care to craft your code into a better design. Small methods!

Book Review: XP Refactored

A copy of the Amazon review of the book Extreme Programming Refactored: The Case Against XP, by Matt Stephens and Doug Rosenberg

Note: This review appeared at Amazon for three months before it was removed, due to a customer complaint about the reference to another reviewer. It was a spotlight review for at least a couple weeks due to the large number of “helpful”/”not helpful” votes it received. The review appears unchanged, except for added links, below.

Additional note (10-Feb-2004): If you’ve arrived at this review from the SoftwareReality web site, you’ll expect a “rant,” “paranoia,” and “anger.” Judge for yourself, but I think the below review is a reflection of what passes for humor in XP Refactored. If my review is a rant (it may well be), then the whole of XP Refactored is one big rant. If my review demonstrates anger (doubtful), then XP Refactored is one massive hate-piece.

**
Some good points ruined by vindictiveness/unsupported claims
Reviewer: Jeff Langr from Colorado Springs, CO United States, September 18, 2003

In XP Refactored, the authors do a good job of covering many of the problems with how XP has been applied. But they waste a large chunk of the book on the Chrysler project (he said, she said), goofy songs (do you old geezers know anything other than the Beatles?), and some things that even the XP community has already admitted were problematic and that have been corrected.

The authors point out (pg93) that the C3 project was cancelled in February 2000, and Beck’s book Extreme Programming Explained came out “later the same year.” This is patently false; a search on this site itself proves that the book came out in October 1999. (Which also meant that Beck probably finished writing the book sometime in the summer of 1999.) My immediate reaction was that if the authors are willing to make up dates in order to rip XP, then what else is dishonest in the book?

I have a bigger problem with the guest testimonials than the authors’ own material. It all started with the disclaimer that many of the testimonials were anonymous, due to the contributors’ fears of reprisal. Once I read that, I wasn’t sure what was written by real people and what–er, who–was made up. Is someone as arrogant and cocksure as David Van Der Klauw a real person?

Each testimonial is just one (made-up?) person’s opinion, and is rarely backed up by any meaningful facts. For example, the possibly fictitious Van Der Klauw claims (pg192) that “many things of moderate or greater complexity cannot be test-first coded.” I’d say he’s wrong. Yes, there is a small number of things that cannot be tested, but by gosh, if any significant portion of your system is so complex that you can’t figure out how to test it, you don’t know much about design. In any case, Van Der Klauw isn’t even sure about his own assertions: “I may change my opinion over time.”

The best fact that Mr. Van Der Klauw has to offer is that he has “13 years of software development experience,” and that should be enough for anyone to believe his countless diatribes.

My biggest beef with the authors’ slam against the actual XP practices is related to refactoring, and to their misunderstanding of its value either with or without respect to XP. While refactoring can result in constantly altering the object-level design or even the architecture of the system, that is something that happens only infrequently in practice (and it can work). Instead, refactoring is best viewed as a means of constantly keeping code clean and maintainable through low-level code changes such as reorganizing methods and renaming things. In fact, this is the bulk of what good refactoring involves. Rarely is there any of the thrashing that the authors repeatedly suggest.

At one point (page 212), the authors recommend that you should never touch a piece of code once it works: “leave it well enough alone.” Wow. Everyone out there is just a perfect coder. Not. Anyone who’s ever hired a high-priced consultant (like good old Doug or Matt) to produce code has been burned by overly complex and often overdesigned code that had to be rewritten because it was completely indecipherable and unmaintainable.

The authors repetitively promote up-front design as a panacea. Fortunately they quietly admit that it’s virtually impossible to produce a perfect design up front, something that just about everybody has agreed upon. The question becomes, how much design should you do up front? The more you do up front, the more of a waste of time it is, if indeed it can’t be perfect.

Nowhere does XP preclude you from spending a half day per iteration–or even longer–to discuss design, produce UML diagrams, etc. In fact, that’s what Object Mentor (the consulting firm of Bob Martin, who is frequently quoted in the book) has recommended in their XP courses.

The authors also recommend writing all requirements down in detail at the start of the project (as in waterfall), and getting a signoff. Never mind the folly of trying to finalize everything up front; worse still is that the authors think that it’s ok for programmers to “spend a few months doing nothing” while waiting for the specs.

Unfortunately, I’ve seen contracts cancelled, jobs lost, and companies fold where the customer wanted to change their mind a few months after the “requirements were complete.” Too bad! You signed here on the requirements, our design is perfect, it’s done, and you can’t change it!

The authors do make concessions to the fact that XP has brought a lot of good things to the table, such as the heavy emphasis on test-driven development. Even the authors’ agile approach resembles much of XP. With this in mind, the absolute hatred that comes through in much of the remainder of the book strikes me as just a bunch of personal vendettas. I understand where they are coming from, as some members of the XP community can be arrogant and annoying (just like the authors), and a lot of XP has been overhyped and misunderstood. Still, one shouldn’t charge people this kind of money in order to air their dirty laundry.

By the way, this book is nowhere near serious, as another well-known reviewer states below. XP Refactored frequently uses words like “moronic” and “asinine” and thus smacks of being an abusive ad hominem attack, not a serious critique.

I was prepared to give the book 3 stars based on some of the value contained within, but there’s just too much vitriol and defensiveness in the book to make it an enjoyable read. Docked a star to 2.

Atom