Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am writing a set of junit test classes in java. There are several constants, for example strings that I will need in different test classes. I am thinking about an interface that defines them and every test class would implement it.

The benefits I see there are:

  • easy access to constants: "MY_CONSTANT" instead of "ThatClass.MY_CONSTANT"
  • each constant defined only once

Is this approach rather a good or bad practice? I feel like abusing the concept of interfaces a little bit.

You can answer generally about interfaces/constants, but also about unit tests if there is something special about it.

share|improve this question

7 Answers 7

Joshua Bloch advises against this in "Effective Java":

That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the classes 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.

You can get the same effect with a normal class that defines the constants, and then use import static com.example.Constants.*;

share|improve this answer

Think it is a viewpoint mostly popular in places where design by contract is prevailent.
Interfaces are contracts. Placing constants in interfaces means every class that abides by the contract agrees to the value/concept identified by the constant.

share|improve this answer
    
interfaces are public contracts. Constant VALUES are private concerns, the public interface should at most expose their names. That's best left to an abstract class. –  jwenting Feb 24 '11 at 8:00
    
Cases in point: javax.naming.Context, javax.ims.Session, and hundreds of such interfaces... –  CMR Feb 24 '11 at 12:02
1  
@jwenting Also, could a public interface "at most expose their names", without exposing the values? –  CMR Feb 24 '11 at 13:17
    
that'd depend on the programming language I guess. In case of Java, no. –  jwenting Aug 1 at 15:05

In our case we're doing this because the values of the constants represent a contract for end states that a service implementation is required to provide. Putting these constants in the interface specifies the end states as a part of the contract, and if any implementation of the interface didn't use them it would not be doing its job.

SOMETIMES constants are implementation details. SOMETIMES they are not. As usual, an engineer needs to use his brain to decide what to do, and not rely on a sweeping pattern or practice.

share|improve this answer

I don't think it's a good thing to have interfaces only for constants.

But if an interface that defines behavior (methods implementing classes should implement), has constants, it's OK. If it *leaks some implementor's detail" into the API, it's becasuse that's the way it should be. They are also leaking than the implementor implements foo and bar methods.

Take for example the java.awt.Transpatency interface. It has OPAQUE, BITMASK and TRANSLUCENT constants but also has getTransparency() method.

If the designer put those constants there it's becasuse he/she thought that would be stable enough to be part of the interface, as getTransparency() is.

share|improve this answer

A company I worked at made heavy use of interface-imported1 constants. I don't feel any harm came of it.

The question you should be asking yourself is, how important is namespacing to you? In the case of constants, that's really all a class acts as. If you have thousands of constants, you may not want all of those constants always available.

The cool thing about interfaces is it gives you the benefit of working either way - bring in all the namespaces you need, or none of them (and access them explicitly, with MyInterface.CONSTANT). Pretty much the same thing as import static MyInterface.*, but a little bit more obvious.


1: If you're not familiar with Java, I don't mean the import keyword, I just mean brought in via implements MyConstantsInterface

share|improve this answer

I come from a background that is mostly influenced primarily by the 'Ada way' and the '.Net way.' I would say no, that it is probably not best to declare constants within interfaces. It is technically not allowed in c#.

The reason I say no is that a an interface is a form of contract that defines behavior, not state or structure. A constant implies some kind of state (primitive), or an aspect of state (composite or aggregate).

I can appreciate the urge to make defaults and predefined values available to everyone who implements the interface, but perhaps the default state would be better described in an abstract or value object or template , where the defaults would have at least minimal context.

For a more technical guide: download.oracle.com/javase/1.5.0/docs/guide/language/static-import.html

share|improve this answer

Yes, It is bad practice. It leaks details to client code, that is not an interface should do.

share|improve this answer
1  
But it isn't an interface, its just using the interface idea to get around Java constraints. –  alternative Feb 19 '11 at 12:17
    
I'd have though if Java wants it to be an interface, then it should be. Anything else ends up being confusing. Java should have a way of doing what you want that isn't a 'bodge'. –  Pureferret Sep 4 '12 at 10:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.