EJB design: Use Interface for declaring Constants
- Posted by: Anil Patel
- Posted on: May 06 2003 18:04 EDT
I use Interface for only declaring Constans. Lot of times my team partners will write class and implement the Interface that has only constants declaration.
I don't see this logical.
I though of using Class with Private constructor and public static final declaration of varaibles for constants.
Any conmments on If this is right to do?
- Yes! by SAF . on May 06 2003 20:49 EDT
- Yes! by Aaron Robinson on May 07 2003 02:43 EDT
- Don't agree but... by Archimedes Trajano on July 06 2004 16:01 EDT
Using an interface for declaring constants is a better idea thatn using a regualr class since, if you use a class, then you will need to qualify the constant with the class name, such as MyClass.CONSTANT_NAME.
If you use an interface, any class that needs to obtain access to the constants would simply need to implement the interface. There would be no need to qualify the constant name in this case, you can use CONSTANT_NAME!
Less typing :-P
I think Joshua Bloch covers this in his book on effective Java. If I remember correctly he recommends not using Interfaces for storing constants.
And the reason for that would be 'what' exactly? Why would using a regular class be better than using an interface?
And the reason for that would be 'what' exactly? Why would using a regular
> class be better than using an interface?
Bloch, p. 89.
"When a class implements an interface, the interface serves as a type that can be used to refer to instances of the class. That a class implements an interface should therefore say something about what a client can do with instances of the class. It is inappropriate to define an interface for any other purpose."
"The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class's exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
There are several constant interface in the Java platform libraries, such as java.io.ObjectStreamConstants. These interfaces should be viewed as anomalies and should not be emulated."
i'm not totally against using interfaces to hold constants. i am however, against having users of those constants implement the constant interface just so they don't have to fully qualify the names. sounds wacky, eh--why not just use an uninstantiable class to hold the constants, then? ok, i'm down with that.
I don't agree with Bloch. It sounds like his opinion rather than a 'best practice'. Interfaces can be used for many different things; an implementation policy, where the inteface contains abstract methods. Interfaces can also serve as an identity marker for a class, or a set of classes that have something in common, and a few good examples of this are the Serializable and Clonable interfaces.
If one reason to avoid the use of a constants-only interface can be justified as to not confuse a programmer, then either that programmer needs more experience to become un-confused, or, perhaps we should not use static initializers as well because I remember reading somewhere that they were not used often and are strange to read, which might confuse a programmer as well :-P. Please, Bloch!
I think it's safe to safe that patience, tedious work, and sometime a litte confusion, comes with the territory. :-)
I tend to agree with SAF ...... maybe we can ask James Gosling ...... when his team designed Java interface, all attributes defined would automatically interpreted by the Java compiler as final and static, which in the other words is a constant. There must be a reason for this ......
Bloch: "When a class implements an interface, the interface serves as a type that can be used to refer to instances of the class. That a class implements an interface should therefore say something about what a client can do with instances of the class. It is inappropriate to define an interface for any other purpose."
This is a rather purist view IMHO, and not very useful for people creating software on a day to day basis. Going on further in the quoting...
"If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface"
The fact of the matter is that most classes in a given system are never sub-classed. And when they are, it is most often done within a closed sub-system.
Further - in the cases when someone does sub-class, the sub-classer is fully aware that its parent implements the interface, and in fact can take advantage of this fact and use the constants directly itself as well.
I can see Bloch's concerns over name space pollution, but in reality it's a rather far fetched proposition. It's only a big concern if you're publishing an API out to a very wide audience, and even then Java APIs tend to expose interfaces more than concrete classes these days, so again it's a non-issue. In fact, Java's single-inheritance of implementation makes this almost a completely moot point.
Anyway, my take on it is that using a constants-only interface is a very, very convenient feature which provides some much needed notational convenience to Java.
And I'll close with a favorite observation of mine that I've been using alot these days: "just because it's written in a book doesn't make it true".
I don't agree with Bloch either. I prefer code compactness and ease of reading. To that effect I don't agree with "implementing" constant interfaces.
However, this is in http://www.fluid.cs.cmu.edu:8080/Fluid/fluid-publications/mot
from Ant it removed 4 constant interfaces that would have
been suggested for 658 variables, from Tomcat it removed
5 constant interfaces that would have been suggested for
855 variables, from J2SDK it removed 1 constant interface
that would have been suggested for 1 variable, from Net-
Beans it removed 13 constant interfaces that would have
been suggested for 4,343 variables, and from Eclipse it removed
4 constant interfaces that would have been suggested
for 4,527 variables.
I am not sure why they did this, maybe because of Bloch's recommendations.
Not sure, but does 1.5 support import static on interface constants? If not I guess that would be one more reason to use classes to hold constants instead of interfaces. Though its still annoying having to read and type public static final every single time.
1.) I think we shouldn't consider import static as a feature to be widely used. Why? Try to read a code fragment that makes use of Collections and other APIs static functions and try to determine what the code does!
2.) IMHO constant interfaces misuse the idea of interfaces. Even if this sounds purist or whatever. Just for comfortability we remove readability. An interface should be seen as a blueprint imho that defines what the class offers. We should only uses Constants in interfaces that are really needed for implementation of it's methods.