I need to create a 100 or more static final constants in my application and I can achieve this is following two ways as per my understanding:
Creating a simple java class and create static final field in that
Creating an interface an put all variable in that because all field in an interface is implicitly static final
I have these question in above approach:
Which one is right approach to achieve this?
Which one is memory efficient approach?
Is there any design pattern to achieve this?
You can refer to many books about the topic.
I will quote a good one: "Effective Java"
Item 19: Use interfaces only to define types
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
you can even check where JDK mostly constants are declared..
Math.PI for example is declared in the class Math and not in an interface
and as an exception you can see constants like in the java.io.ObjectStreamConstants but again the Books are there to help:
From effective java again:
There are several constant interfaces in the Java platform libraries...
These interfaces should be
regarded as anomalies and should not be emulated.
I would not be thinking should they be in an interface or class, but more about the constants and their meaning.
I would not recommend putting all your constants in one place for the sake of keeping them together. If for instance a constant is directly related to a class then would say put it in that class. I have worked with code where all the constants ate bundled into one class, and I don't thing it is a good approach.
Have you considered approach with ENUM or it doesn't fit in your case?
I think, the approach with ENUM can gives you some benefits over constants.
Why use Enums instead of Constants?
I think that convenient way is to keep them in one place, if they are have common nature. Anyway, they should be grouped by some attribute. You can create class for them like this:
public final class Consts {
public static class GroupA {...}
public static class GroupB {...}
//and so on
}
With groups this class becomes much readable and a little bit better manageable. About memory consumption, try to use primitives for your constants, because they do not require additional space for meta information.
You can create Final or static constraint much as you like just by declaring field inside interface class so i would like to go with your option number 2
Related
Time after time I have a situation where I have an utility class containing only static methods.
The question is not about the fact of having such classes themselfes, so not a debate about utility classes. We just assume that there is a use case where this class makes sense.
Now I have seen different possibilities to prevent instantiation/extension:
a private constructor and final class
using an enum instead of a class
What is the best practice here? Could you elaborate the benefits/drawbacks of the two possibilities?
Personally I prefer the enum solution, as it completely prevents instantiation and extension out of the box, but maybe I am wrong.
Thank you already!
I would prefer the former.
First of all, using a final class with a private constructor is what I do all the time when I'm writing a utility class. I have never even thought of using enums.
The main reason for not using an enum is that you can still technically write something like this:
MyEnum var = MyEnum.valueOf("Hello");
and the compiler doesn't say a thing about it, not even IntelliJ IDEA!
I have a question regarding the design of my program. I have a class A that stores public constant so that i can use these constants in another class.
public static final String error_code1 = "Fatal Error";
public static final String error_code2 = "XXXX";
...
...
Between Composition vs Interface, i dont know which 1 is more suitable. From what i think, since i only need the constants for value-comparing in my program, so i think composition is enough (low coupling).
But can you guys give me some advice/arguments from software deign point of view? (cohesion, coupling, difficulties of maintenance, etc )
First of all I'd recommend you to use an enum for this case.
public enum ErrorCode {
FATAL_ERROR("Fatal Error"),
X_ERROR("XXXX");
public final String msg;
private ErrorCode(String msg) {
this.msg = msg;
}
}
If this doesn't suit you for some reason, I'd go with a final utility class with private (unused) constructor.
Regardless, since the fields are static and final, I would not consider having a reference to A or implement A to get hold of the constants.
Adding constants to interfaces is considered an anti-pattern since the primary purpose of an interface is to define behavior contracts. Use either an enum or access them directly since they are public.
I wouldn't use interface to store constant as having 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][1], 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.
I would personally go for enum and if needed i could even use it to have error code or add relevant field/method as well.
String/int/... constants in another class have one problem: they are copied into the using class' constant pool, and after that no import to the original class exists. Should you then alter a constant's value, the using class is not forced to be recompiled.
The solution would be to use an interface, and "implement" that interface; ugly maybe.
Better is to use an enum.
For open ended value domains one would not use an enumeration, but an object oriented approach:
abstract class ParseError extends RuntimeException
class ExpressionExpectedError extends ParseError
class DigitsMayNotFollowLeadingZeroError extends ParseError
..
In the javadoc one might see all child classes of ParseError. Here the classes themselves form the domain values, and an instantiation bears the actual context information. That is more OOP. Calling several methods on an object is better than having several switches on constants. An enum however may be used with categorical method too: boolean errorHandledBySkippingToNextExpr().
I had been looking at some code developed by an off-shore group. I see at least one "constant interface" per module defined.
Example (not real world) :
public interface RequestConstants{
//a mix of different constants(int,string,...)
public static final int MAX_REQUESTS = 9999;
public static final String SAMPLE_REQUEST = "Sample Request";
}
Per my understanding it is an anti-pattern as these does not any utility in run-time, and should be avoided or tackled in a different way.
What are elegant ways to represent this? Can enums be used instead?
I prefer to put constants in the class where they make they're most relevant, and then if I have to refer to them elsewhere, just do so - possibly using static imports if that makes sense (e.g. for Math.PI).
The only real reason to put constants in interfaces was to allow you to "implement" the method-free interface and get access to the constants via their simple names without any further qualification. Static imports remove that reason.
En enum is probably not a good idea unless all the parameters are closely related. With the two parameters in your example I'd say they are not closely enough related to qualify as an enum.
But it's not necessarily a Bad Idea to include a constants class / interface like this. It does have the advantage of being centralized, which means this configuration stuff can easily be moved outside of the program -- for instance to a properties file, a command-line decoder, a database or even a socket interface -- with minimal impact to the other classes. It's really a question of what direction the design will take.
Unless you are thinking of going down that path, however, I'd say static finals in the classes where the respective parameters are used is the way to go, as has been suggested already.
Turn the interface into a final class with a private constructor.
Use final non-instantiable class, i.e. one with a private constructor.
In his book Effective Java, Joshua Bloch recommends against using Interfaces to hold constants,
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 con-stants, 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.
His reasoning makes sense to me and it seems to be the prevailing logic whenever the question is brought up but it overlooks storing constants in interfaces and then NOT implementing them.
For instance,
public interface SomeInterface {
public static final String FOO = "example";
}
public class SomeOtherClass {
//notice that this class does not implement anything
public void foo() {
thisIsJustAnExample("Designed to be short", SomeInteface.FOO);
}
}
I work with someone who uses this method all the time. I tend to use class with private constructors to hold my constants, but I've started using interfaces in this manner to keep our code a consistent style. Are there any reasons to not use interfaces in the way I've outlined above?
Essentially it's a short hand that prevents you from having to make a class private, since an interface can not be initialized.
I guess it does the job, but as a friend once said: "You can try mopping a floor with an octopus; it might get the job done, but it's not the right tool".
Interfaces exist to specify contracts, which are then implemented by classes. When I see an interface, I assume that there are some classes out there that implement it. So I'd lean towards saying that this is an example of abusing interfaces rather than using them, simply because I don't think that's the way interfaces were meant to be used.
I guess I don't understand why these values are public in the first place if they're simply going to be used privately in a class. Why not just move them into the class? Now if these values are going to be used by a bunch of classes, then why not create an enum? Another pattern that I've seen is a class that just holds public constants. This is similar to the pattern you've described. However, the class can be made final so that it cannot be extended; there is nothing that stops a developer from implementing your interface. In these situations, I just tend to use enum.
UPDATE
This was going to be a response to a comment, but then it got long. Creating an interface to hold just one value is even more wasteful! :) You should use a private constant for that. While putting unrelated values into a single enum is bad, you could group them into separate enums, or simply use private constants for the class.
Also, if it appears that all these classes are sharing these unrelated constants (but which make sense in the context of the class), why not create an abstract class where you define these constants as protected? All you have to do then is extend this class and your derived classes will have access to the constants.
I don't think a class with a private constructor is any better than using an interface.
What the quote says is that using implements ConstantInterface is not best pratice because this interface becomes part of the API.
However, you can use static import or qualified names like SomeInteface.FOO of the values from the interface instead to avoid this issue.
Constants are a bad thing anyway. Stuffing a bunch of strings in a single location is a sign that your application has design problems from the get go. Its not object oriented and (especially for String Constants) can lead to the development of fragile API's
If a class needs some static values then they should be local to that class. If more classes need access to those values they should be promoted to an enumeration and modeled as such. If you really insist on having a class full of constants then you create a final class with a private no args constructor. With this approach you can at least ensure that the buck stops there. There are no instantiations allowed and you can only access state in a static manner.
This particular anti-pattern has one serious problem. There is no mechanism to stop someone from using your class that implements this rouge constants interface.Its really about addressing a limitation of java that allows you to do non-sensical things.
The net out is that it reduces the meaningfulness of the application's design because the grasp on the principles of the language aren't there. When I inherit code with constants interfaces, I immediately second guess everything because who knows what other interesting hacks I'll find.
Creating a separate class for constants seems silly. It's more work than making an enum, and the only reason would be to do it would be to keep unrelated constants all in one place just because presumably they all happen to be referenced by the same chunks of code. Hopefully your Bad Smell alarm goes of when you think about slapping a bunch of unrelated stuff together and calling it a class.
As for interfaces, as long as you're not implementing the interface it's not the end of the world (and the JDK has a number of classes implementing SwingConstants for example), but there may be better ways depending on what exactly you're doing.
You can use enums to group related constants together, and even add methods to them
you can use Resource Bundles for UI text
use a Map<String,String> passed through Collections.unmodifiableMap for more general needs
you could also read constants from a file using java.util.Properties and wrap or subclass it to prevent changes
Also, with static imports there's no reason for lazy people to implement an interface to get its constants when you can be lazy by doing import static SomeInterface.*; instead.
In Effective Java, Item 17, Josh Bloch argues that putting static members into an interface (and implementing that interface) is a bad practice known as the Constant Interface Antipattern:
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.
I'm pretty confident I understand the reasoning behind this and completely agree.
My question is: is grouping related constants (note: these are NOT suitable for an enum, consider the math example of the related constants pi and e) in an interface versus a non-instantiable class a good idea, provided you only access the values via static references and static imports, keep the interace hidden from your API w/ a default access modifier, and never actually implement the interface?
Why or why not? Are there any advantages are there to grouping them in a class other than being able to use a private constructor to ensure the constant grouping type is never instantiated?
Let's put it the other way. There is no advantage of using interfaces for constants. As you know, interfaces are for defining contracts, not for constants. I don't see the problem of changing the interface keyword to class keyword and using public static final fields for example. Using interfaces for keeping constants is never a good idea. I think people use this anti-pattern because they don't know about static imports(it was introduced in Java 5.0) or they are too lazy to dispatch their constants in the appropriate classes. Instead they just create one interface and let every class implement it.
Edit: By the way the question sounds me like - Is it a good idea to watch television, looking at the neighbourhood's TV using a telescope, provided the seeing is good. The answer is simple - no, the telescope is invented for other things. Ah, and I know this example is dumb:)