Interfaces For Defining Constants

Motivation

Assume you have a large (WhatIsLarge? ?) set of constants, e.g. protocol parameters, you need in separate contexts in your code, by multiple StakeHolders.

You of course want to have symbolic names for the constants, to avoid mismatch and errors of using the values all over your code.

Solution

To separate the definition of constants and the usage of these constants, define the constants in an interface. This provides an own NameSpace for the constants which can then be used by multiple "StakeHolders", including

Disadvantages

Alternatives

Known Usages


I see the utility of this, but something inside me rebels at using InterfacesForDefiningConstants. Somewhere in the back of my mind is the notion that interfaces are specifications rather than implementations. Using constants in the interface allows you to parameterize behavior by changing their values and recompiling. Sort of a poor man's macro preprocessor. -- MichaelFeathers
In some sense I agree, in another sense I don't. I have to deal with a lot of communication protocols. Protocols are, simply said, part of some physical interface between two entities. Protocol definitions usually contain large sets of constants (maximum MTU, timeouts, counters, etc.). Since the protocol specs don't change fast (if at all), these constants "never" change. They are not supposed to change at all, they are really "constant" :-))

The constants are not really parameters of a protocol, but an integral, defined part of a protocol specification. Using an interface for specifying such constants seems natural to me. -- ThomasWeidenfeller


Concerning Disadvantages. If you want to output constants in more-less readable form, you may create a small nested class in this interface, say called Constant, which contains not only the value of the constant but also any additional information such as the name of the constant. Then you may create any constant as an instance of Constant class (certainly, final and public). -- KirillStepanosov


Could someone please try and relate this page to the page about EnumeratedTypesInJava?

Of course. In EnumeratedTypesInJava people try to work around the non existing enum implementation in Java. They need features, which include:

EnumeratedTypesInJava is not really about values. A main idea about enumerations is to NOT have to deal with (integer) numbers, since what you model might not have anything to do with numbers at all (enumerations mapping directly to integers is something taken from C, look at how Pascal handles this differently). E.g. you have an object chocolate. It could have an attribute called taste. taste could either have the value SWEET or BITTER. Representing SWEET as a 1, and BITTER as a 0 would be totally artificial, because these attributes don't have numeric integer values (however, on a lower level in the computer this is a good idea for representation). In Java and other C-style language this is, however, what has to be done by the programmer: to assign integer values for these type of attributes/enumerations - and people don't like it.

InterfacesForDefiningConstants , on the other hand, is all about values. One is just looking for symbolic names and grouping for some values. The values matter, but typing the same number several times in different parts of the code is not a good idea. The values even don't necessarily have to be some kind of enumeration.

Assigning symbolic names to the constants, and group them, could also be done with some C-style enumeration type - if it would be in the language. Or with C-like macros - if macros would be in the language.

-- ThomasWeidenfeller


This seems to be a violation of data encapsulation. Constants only have meaning in relationship to the variables that acquire their values. If the variables are well encapsulated, then the constants can be as well. If you need to use the same constant in multiple classes, I would review your class structure. It sounds like a code section that needs simplification. --WayneMack


Re: Violation of data encapsulation

Well, maybe yes, maybe no.

-- ThomasWeidenfeller


I've used also this idiom for protocols and for data base schemas. It looks a clear way of specifying external dependencies with very little work. Nevertheless, I'm still looking for a pattern that suits better to the case of data base schemas. --JoseGAlejandre


I am confused on this. Perhaps a small example might help. Why 'interfaces' instead of normal objects?

So you can shove the constants into the namespace of your classes by implementing the Interface. --MartinSchwartz

 public interface FooConstants {
    int cDog = 1;
    int cCat = 2;
    int cMouse = 3;
 }

public interface BarConstants { int cHouse = 1; int cVilla = 2; int cPalace = 3; }

public class FooBar implements FooConstants, BarConstants { ... switch ( barType ) { // fully qualified form: case BarConstants.cHouse:

// abbreviated form: case cVilla: ... } ... }

[Ew--gross. (Somebody needed to weigh in on the opposing side.) If you ever do that, you might want to specify in the contract documentation that clients of FooBar must not depend on the publicly visible fact that FooBar implements FooConstants?.

Actually, in Java 1.5 you can now say something like "import static FooConstants?.*" to accomplish the same simplification of the code without changing the public interface of your class.

-- DanielBarclay?]


The only advantage of using interfaces is that you don't need to retype the interface name everywhere that a constant is used *if* the class using the constants interface 'implements' that interface (using the term implements loosely here, since it's not really implementing anything). The disadvantages of polluting your classes with these 'interfaces' far outweighs the advantage, especially if the constants are only implementation detail (e.g. not passed to or returned from methods of the interface/implementation class). It might make sense to define the constants in the interface though, if they are part of the contract for that interface (i.e. expected parameter or return values from methods of that interface). The can be better done with (often final) classes (IMHO), e.g.:

public final class DoorState? {

 '' private DoorState?() { ; } // prevent instantiation of this class.

'' public static final int OPEN = 0; '' public static final int CLOSED = 1; '' public static final int AJAR = 2;

}

Better still use the JavaTypeSafeEnum? idiom.

P. J. Lewis


By using interfaces to define constants (unless actually applicable to the interface), you lose name space. By using a final class to define global constants, you do not lose name space (yeah, I hate using classes for namespace, but lacking a real alternative in Java, you have to work with what you got).

How do you lose name space? Interface A-prime defines some constants without defining an actual protocol (i.e. real interface, the interface is present only to define constants), class A implements A-prime, class B derives from A, and class BB derives from B...now class BB references a constant from A-prime without qualification (e.g. A-prime.constant), time to start searching!


I don't see why you can't use:

class Constants {

	private Constants()
	{
	}

public static final int A_CONSTANT=5; etc.

}

Interfaces for namespace purposes only gains you brevity, and you can achieve some brevity like this:

Constants c; something(c.A_CONSTANT);

Maybe this is all moot now that 1.5 is out, I haven't looked into enums yet.

RickyClarkson


CategoryInterface Category: JavaIdioms


See also: DefineConstantsInInterfaces
EditText of this page (last edited December 8, 2004)
FindPage by browsing or searching

This page mirrored in JavaIdioms as of April 29, 2006