'''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 * Multiple implementations of the same API * Clients of an API * Design tools '''Disadvantages''' * The usage of an interface does not allow to implement a mechanism for converting the constants to a visible/human readable representation. * If the constants are an "implementation detail", an interface might not be the natural place for the value (CodeSmell''''''s, ListenToTheCode). * Due to Java compiler optimization, complete code recompilation of all classes using the constants is necessary if a constant changes. Just changing the interface and recompiling it does not work (this is, however the case with all constants defined as 'static final') '''Alternatives''' * If run-time configuration is an issue: ParameterBlock '''Known Usages''' * Swing ---- 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: * A printed representation of an enum (which is a problem when it comes to internationalization) * A way to iterate over the value set of an enumeration. 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. * Since the basic type in Java are not objects (int, double, etc.), they can not simply be associated with a value range. Encapsulating each int in an own class, only because its value range is limited under a certain condition might be too much work. * I already mentioned protocol implementations. Here you have a client and a server component. Bot HAVE to agree on the same parameters. Encoding these parameters in one place, instead multiple places, seems to be a good idea for me (OnceAndOnlyOnce). * Recently started to code a special chart widget. Lots of constants (distance between items, item sizes, page sizes, zoom factors, etc. pp.). More than 80 constants. Just to keep an overview, I separated the constants from the algorithms (graph layouting is "fun"). You can now configure the widget independently, without the need to wade through the algorithms. * Not all 'Constants only have meaning in relationship to the variables that acquire their values.' Factors to convert from metric to imperial units are independent of the actual variable holding them. Scientific constants are independent of variables holding them. I guess you mix up units and constant values. -- 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 Foo''''''Constants { '' '' int cDog = 1; '' '' int cCat = 2; '' '' int cMouse = 3; } public interface Bar''''''Constants { '' '' int cHouse = 1; '' '' int cVilla = 2; '' '' int cPalace = 3; } public class Foo''''''Bar implements Foo''''''Constants, Bar''''''Constants { '' '' ... '' '' switch ( barType ) { '' '' '' '' // fully qualified form: '' '' '' '' case Bar''''''Constants.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