Why do we use an Interface? It is used to achieve total abstraction. Since java does not support multiple inheritances in the case of class, by using an interface it can achieve multiple inheritances. It is also used to achieve loose coupling.
Java programmers commonly define constants inside their interfaces, if it makes design sense. You can do so using variables in an interface because the values will be present instantly at runtime and their values shared among all classes implementing your interface, because they are static and final.
Interface variables are static because java interfaces cannot be instantiated on their own. The value of the variable must be assigned in a static context in which no instance exists. The final modifier ensures the value assigned to the interface variable is a true constant that cannot be re-assigned.
Putting static members into an interface (and implementing that interface) is a bad practice and there is even a name for it, the Constant Interface Antipattern, see Effective Java, Item 17:
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 interfaces in the java platform libraries, such as
java.io.ObjectStreamConstants
. These interfaces should be regarded as anomalies and should not be emulated.
To avoid some pitfalls of the constant interface (because you can't prevent people from implementing it), a proper class with a private constructor should be preferred (example borrowed from Wikipedia):
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
And to access the constants without having to fully qualify them (i.e. without having to prefix them with the class name), use a static import (since Java 5):
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
"The constant interface pattern is a poor use of interfaces"
Whoever concocted this hypothesis, however a guru he/she may be, concocted it on the basis of the need to continue implementing bad habits and practices efficiently. The hypothesis is based on the promotion of the validity of bad software design habits.
I wrote a response rebuttal against that hypothesis here: What is the best way to implement constants in Java? explaining the baseless-ness of this hypothesis.
For 10 years that question had stayed open, until it was closed within 2 hours after I posted my reasons dejustifying this hypothesis, thus exposing UNWILLINGness for debate by those who hold on to this misguided hypothesis dearly.
These are the points I expressed against the hypothesis
The basis for holding this hypothesis is the need for methods and RESTRICTIVE rules to cope with the effects of bad software habits and methodologies.
The proponents of the sentiment "The constant interface pattern is a poor use of interfaces" are unable to provide any reasons other than those caused by the need to cope with the effects of those bad habits and practices.
Solve the fundamental issue.
And then why not make full use and exploit every language feature of the Java language structure to your own convenience. No Jackets Required. Why invent rules to barricade your ineffective lifestyle to discriminate and incriminate more effective lifestyles?
is information organisation. Information mediating the process, nd the behaviour of that information should first be understood, along with the so-called business rules - before engineering or supplementing solutions to the process. Such method of information organization was called data normalization a few decades ago.
Then only the engineering of a solution be possible because aligning the granularity and modularity of the components of a solution with the granularity and modularity of the components of the information is the optimal strategy.
There are two or three significant obstacles toward organizing information.
The lack of perception for the need of data-model "normalization".
EF Codd's statements on data normalization are flawed, defective and ambiguous.
The latest fad masquerading as agile engineering is the misguided notion that one should not plan and condition the organization of modules ahead because you can refactor as you go. Refactoring and continuous change without being impeded by future discoveries is used as the excuse. Essential discoveries of behaviour of process information is then, by using accounting tricks to delay profits and assetization, wherefore essential knowledge and their treatment is deemed not needed now.
Don't make up rules or issue any fatwa against it just because you love your ad-hoc hit-and-run programming habits.
Do not ban gun ownership with the reason that there are people who either do not know how to handle guns or are prone to abuse guns.
If the rules you concoct are meant for programming novices unable to code professionally and that you count yourself amongst them then say so - do not declare your fatwa as applicable to properly normalized data-models.
I don't care what the original intentions of the founding fathers had for the US Constitution. I don't care about the unwritten uncodified intentions. I only care about what is literarily codified in the written Constitution and how I can exploit them for the effective functioning of society.
I only care about what the Java language/platform specs allow me and I intend to exploit them to the full to afford me a medium to express my software solutions efficiently and effectively. No jackets required.
It requires writing extra code to map parameter to value. The fact that the founders of Java did not provide for parameter-value mapping without your writing that mapping code demonstrates Enum Constants are just as unintended use of Java language.
Especially since you are not encouraged to normalize and componentize your parameters, there would be a false impression that parameters mixed into an Enum bag belong to the same dimension.
Don't forget that. If you designed and normalized your data-model, and they include constants,then those constants are contracts. If you did not normalize your data-model, then you should conform to fatwas given on how to practice restrictive coding to cope with that bad habit.
Therefore, Interfaces are a perfect way of implementing Constants' contract.
Yup. Anyone could inadvertently implement any interface inadvertently. Nothing will stand in the way of such inadvertent programmers.
Do not place restrictive decrees to protect presumed bad practices that cause leaking of uncontracted/stray parameters into API. Solve the fundamental issue, rather than place the blame on Interface Constants.
A normal functioning and EFFECTIVE programmer is not there to prove how long she can stay underwater, how far she could walk in blistering heat or wet thunderstorms. She is to use an efficient tool like a car or bus or at least a bike to take her 10 miles to work everyday.
Do not place restrictions on fellow programmers just because you have an esoteric asceticism obsession with IDE-less programming.
OSGI is such a framework. And so is the decree against Interface Constants too.
Interface constants are an effective and efficient way to place into Contract well-designed and normalized components of a data-model.
Interface constants in an appropriately named private interface nested in a class file are also good practice to group all your private constants rather than scatter them all over the file.
I came across this old question several times now and the accepted answer still confuse me. After a lot of thinking, I think this question can be further clarified.
Just compare them:
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
vs
public interface Constants {
double PI = 3.14159;
double PLANCK_CONSTANT = 6.62606896e-34;
}
Same usage. Much less code.
I think @Pascal Thivent 's answer has the wrong emphasis, here is my version of it:
Putting static members into an interface (and implementing that interface) is a bad practice.
The quote from Effective Java has the assumption of the constant interface being implemented by others, which I think should not (and will not) happen.
When you create an constant interface named something like Constants
, it should not be implemented by anyone. (though technically possible, which is the only issue here)
The standard library cannot afford any possible misuse of the design, so you just won't see any there.
However, for daily projects of normal developers, using constants interface is a lot easier because you do not need to worry about static
, final
, empty constructor
, etc, and it will NOT cause any bad design issue. The only downside I can think of is that it still has the name of "interface", but nothing more than that.
At the end, I think everyone is just quoting from books, and giving opinions and justifications to their stands. No exception for me. Maybe the decision is still up to the developers of each project. Just go ahead to use it if you feel comfortable. The best we can do is to make it consistent throughout the project.
Joshua Bloch, "Effective Java - Programming Language Guide":
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.
They are useful if you have common constants that will be used in classes that implement the interface.
Here's an example: http://www.javapractices.com/topic/TopicAction.do?Id=32
But note that the recommended practice is to use static imports instead of constants in interfaces. Here's a reference: http://www.javapractices.com/topic/TopicAction.do?Id=195
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With