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
add comment

5 Answers

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
add comment

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
add comment

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
add comment

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
add comment

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
add comment

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.