• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

constants (only) in interfaces

 
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Greetings, in my workplace I've noticed quite a few interfaces containing only constants (dozens of them), having read (many times): Effective Java: Programming Language Guide, by Joshua Bloch, (rule 17 states: Use interfaces only to define types) I sent out a note stating that we should stay away from this practice, I received a reply back that there were good reasons for using interfaces containing only constants (see below), however, I can think of several ways around the stated reply (just takes a little work).

Question: am I wrong about this, or are there good reasons for taking the easy way out?


(Reply received back)
I agree that we should not abuse the usage of the constants interface - especially creating a giant interface to capture all the constants is not a good practice (breaks the encapsulation). But there is merit using constant interface rather than a constant class or enum.

In my opinion, there are a few examples of using constants interface.
- The name of the attributes/parameters in HttpServletRequest/HttpServletSession so that multiple Actions, Servlets and JSPs are to use the same value (avoid typo).
- The ActionForward names used to match the struts-config.xml
- DAO DB column constants

By defining them as constants, you can take advantage of multiple inheritance of interfaces to access constants defined in multiple base interfaces. Although the constants are not type safe, they do limit the values used in different classes.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Tom Bigbee:
By defining them as constants, you can take advantage of multiple inheritance of interfaces to access constants defined in multiple base interfaces. Although the constants are not type safe, they do limit the values used in different classes.


This is called the Constant Interface Antipattern according to Effective Java.

The problem with this is that if you are implementing an interface like that, you are introducing all the constants in the interface into the public API of your class. That's a bad thing. The public API of your class should be as small as possible if you want to write maintainable software; it should certainly not contain a whole lot of constants that are only needed for the internals of the class.

To get rid of this problem static import was added to Java 5. So, you should use static import instead.

Unfortunately this anti-pattern has been used in several places in the Java API itself. That doesn't justify its use in your own code...

Did you show the people you've e-mailed with your Effective Java book?
[ June 20, 2007: Message edited by: Jesper Young ]
 
Tom Bigbee
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, I did show them the Book, version 5 does take care of the issue with the Static Import, however we are still on jdk1.4 and j2ee 1.4, so you're both right, thanks
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think it's helpful to pay attention to who exactly needs to use these constants. Bloch's arguments apply to classes that use constants internally. They don't really apply to classes that intentionally make those constants available to clients, as part of their own APIs.

For example, consider WindowConstants. The three classes that implement this are JDialog, JFrame, and JInternalFrame. They all have some common behavior, setDefaultCloseOperation(). This method really should have been defined in the same interface - let's call it ClosableWindow:

Here the constants are intended to be used by clients of JDialog, JFrame, and JInternalFrame - and it makes perfect sense for those clients to see the constants as part of the API. However it would not make sense for those clients to implement this interface just so they can use the constants. If my class JimsTetrisGame uses a JFrame, that's fine. But people who use my class don't need to read about DISPOSE_ON_CLOSE etc, because it's not something they need to call in code in order to use my class. So I shouldn't implement WindowConstants or ClosableWindow just to make my life a tiny bit easier inside the JimsTetrisGame class, because that would unnecessarily affect the public API of my class.

Here we see that defining the method setDefaultCloseOperation() inside ClosableWindow is helpful. Because If I'm writing JimsTetrisGame and I want to implement WindowConstants just for my own convenience, nothing's stopping me. (Other than the fact I am aware this is an antipattern.) But with ClosableWindow, it's different, because I can't implement that without implementing the method setDefaultClosableOperation(). And when I start to do that, I realize that this method isn't something that clients of my class need - therefore it shouldn't be part of my public API.

Note that Bloch doesn't say you shouldnever put constants in interfaces. He recommends against defining interfaces just to make internally-used constants more accessible. But if the constants are intentionally part of the API, and if the interface also defines one or more methods that use those constants, that's a different story, much more justifiable.

Note that for most of the examples I can think of, it would be preferable to use an enum to define the list of values that are used by a method. Or prior to JDK 5, you could use the type-safe enumeration pattern. But this wasn't known - at least, not widely known - at the time many standard library classes were designed. A more modern version of ClosableWindow would be:

I suspect that for many of the examples Tom's co-worker is thinking of, putting constants in interfaces is similarly justifiable - clients do need to use them. Together with methods that take those constants as parameters. And since enums are not available (JDK 1.4), the type-safe enumeration pattern is worth considering.
[ June 21, 2007: Message edited by: Jim Yingst ]
 
Tom Bigbee
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jim

Thanks, very much for your comments, they were very imformative

Thomas
 
reply
    Bookmark Topic Watch Topic
  • New Topic