Reasoning behind not using non-implemented Interfaces to hold constants? - java

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.

Related

Static final field in a class vs Interface field in java

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

Fields in interfaces

I have a basic question in Java, but it's a general question in OOP. Why do interfaces allow fields to be set? Doesn't that run contrary to what an interface is supposed to do?
The way I made sense of it, an interface is what in English would be an adjective. So, if my class implements the interfaces Runnable and Serializable, I'm ensuring the user that my class will satisfy the conditions to be Runnable and Seriablizable. However, that would mean interfaces are "stateless", but they are allowed to have fields in Java...
Am I missing something?
All fields in interface are public static final, i.e. they are constants.
It is generally recommended to avoid such interfaces, but sometimes you can find an interface that has no methods and is used only to contain list of constant values.
First of all, there's difference between OOP paradigm and OOP implementation in Java, so same words may mean a bit different things.
In OOP the paradigm interface is what you can do with the object (or what object can do for you). Any object can have several interfaces and thus play different roles. For example, someone may work as a programmer and be able to create programs, but at the same time he may be a husband and father and thus be able to pay the bills for his family and take care of children. Here "programmer", "husband" and "father" are interfaces, and a person is an object that implements them. Note, that interfaces do not imply presence of any specific features (fields) for implementing object, just actions that this object should be able to perform.
Java more or less follows this idea, but as any paradigm implementation has its own features. Java allows describing methods, that is actions that the implementing object should be able to perform, but not any implementation details, thus, nothing about object fields or private methods.
But what about constants (public final static fields)? Are they part of implementation or interface. It could be both. E.g. interface "programmer" can have constant WORK_HOURS set to "8". Thus Java allows you to describe constants in interfaces too.
Note, that Java only helps you to make good OOP design, but it doesn't strongly require it. In particular, not all public methods of an object should exist in interface too. For example, getter and setter methods are normally public, but in fact they are the part of implementation, not interface, and thus it's worth not to bring them into interface.
(Please also note, that most things I described here are about mainstream OOP like in Java, but there are also other kinds of OOP such as prototype-based one, in particular implemented in JavaScript).
What if that interface refers to constants? Wouldn't it be natural to declare them in the interface?
interface IdFinder {
Serializable UNSAVED = new Serializable() {};
/** #returns the given entity's persistent identity,
or {#link UNSAVED} if it hasn't been saved yet,
or null if o is a value object that hasn't a
persistent identity of its own.
*/
Serializable getId(Object o);
}
Yes, you can have constant fields in interfaces, but you are right when you say that "it seems contrary to what an interface is supposed to do", as it is not a good practice. Why would you want to have all your classes that implement an interface with the same constants? You could simply have them in the class that uses them, or if you really need to export them somehow, have them in a separate class utiliy like this:
public class Constants {
private Constants() { }
public static final int ZERO = 0;
public static final int SOME_COMPLEX_NUM = 2124132L;
...
}
You also have enums, if you need to represent a set of constant fields with some meaning. I do not see any "use case" where you would actually need constants in an interface. But could be wrong :)

What are most graceful alternatives to constant interfaces?

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.

Java Code Style -- Interfaces vs. Abstract Classes

A new collaborator of mine who was reviewing some code I'd written told me that she wasn't used to seeing interfaces used directly in Java code, e.g.:
public interface GeneralFoo { ... }
public class SpecificFoo implements GeneralFoo { ... }
public class UsesFoo {
GeneralFoo foo = new SpecificFoo();
}
instead, expecting to see
public interface GeneralFoo { ... }
public abstract class AbstractFoo implements GeneralFoo { ... }
public class SpecificFoo extends AbstractFoo { ... }
public class UsesFoo {
AbstractFoo foo = new SpecificFoo();
}
I can see when this pattern makes sense, if all SpecificFoos share functionality through AbstractFoo, but if the various Foos have entirely different internal implementations (or we don't care how a specific Foo does Bar, as long as it does it), is there any harm in using an interface directly in code? I realize this is probably a tomato/tomato thing to some extent, but I'm curious if there's an advantage to the second style, or disadvantage to the first style, that I'm missing.
If you have no need for an abstract class with certain details common to all implementations, then there's no real need for an abstract class. Complexity often gets added to applications because there is some perceived need to support future features that haven't yet been defined. Stick with what works, and refactor later.
No, she's inexperienced, not right. Using interfaces is preferred, and writing redundant abstract super classes for the sake of redundancy is redundant.
UsesFoo should care about the behaviour specified by the interface, not about the super class of its dependencies.
For me "she wasn't used to" is not good enough reason. Ask her to elaborate on that.
Personally I'd use your solution, because:
AbstractFoo is redundant and ads no value in current situation.
Even if AbstractFoo was needed (for some additional functionality), I'd always use lowest needed type: if GeneralFoo was sufficient, then I'd use that, not some class derived from it.
It depends only on your problem.
If you use interfaces only, then if all your classes have a same method, it would have to be implemented redundantly (or moved away to a Util class).
On the other hand, if you do write an intermediary abstract class, you solved that problem, but now your subclass may not be a subclass of another class, because of absence of multiple inheritance in Java. If it was already necessary to extend some class, this is not possible.
So, shortly - it's a trade off. Use whichever is better in your particular case.
There is not harm in directly using an interface in code. If there were, Java would not have interfaces.
The disadvantages of using an interface directly include not being able to reach and class-specific methods which are not implemented in the interface. For poorly written interfaces, or classes which add a lot of "other" functionality, this is undesirable as you lose the ability to get to needed methods. However, in some cases this might be a reflection of a poor design choice in creating the interface. Without details it is too hard to know.
The disadvantages of using the base class directly include eventually ignoring the interface as it is not frequently used. In extreme cases, the interface becomes the code equivalent of a human appendix; "present but providing little to no functionality". Unused interfaces are not likely to be updated, as everyone will just use the base abstract class directly anyway. This allows your design to silently rot from the viewpoint of anyone who actually tries to use the interface. In extreme cases, it is not possible to handle an extending class through the interface to perform some critical functionality.
Personally, I favor returning classes via their interface and internally storing in members them via their lowest sub-class. This provides intimate knowledge of the class within the class's encapsulation, forces people to use the interface (keeping it up-to-date) externally, and the class's encapsulation allows possible future replacement without too much fuss.
I'm curious if there's an advantage to the second style, or disadvantage to the first style, that I'm missing
That reasons for the first interfaces style:
Often, the design is such that the interface is the public interface of the concept while the abstract class is an implementation detail of the concept.
For example, consider List and AbstractList in the collection framework. List is really what clients are usually after; fewer people know about about AbstractList because its an implementation detail to aid suppliers (implementers) of the interface), not clients (users) of the class.
The interface is looser coupling, therefore more flexible to support future changes.
Use the one that more clearer represents the requirement of the class, which is often the interface.
For example, List is often used rather than AbsrtactList or ArrayList. Using the interface, it may be clearer to a future maintainer that this class needs some kind of List, but it does not specifically need an AbstractList or an ArrayList. If this class relied on some AbstractList-specific property, i.e. it needs to use an AbstractList method, then using AbstractList list = ... instead of List list = ... may be a hint that this code relies on something specific to an AbstractList .
It may simplify testing/mocking to use the smaller, more abstract interface rather than to use the abstract class.
It is considered a bad practice by some to declare variables by their AbstractFoo signatures, as the UsesFoo class is coupled to some of the implementation details of foo.
This leads to less flexibility - you can not swap the runtime type of foo with any class that implements the GeneralFoo interface; you can only inject instances that implement the AbstractFoo descendant - leaving you with a smaller subset.
Ideally it should be possible for classes like UsesFoo to only know the interfaces of the collaborators they use, and not any implementation details.
And of course, if there is no need to declare anything abstract in a abstract class AbstractFoo implements GeneralFoo - i.e. no common implementation that all subclasses will re-use - then this is simply a waste of an extra file and levels in your hierarchy.
Firstly I use abstract and interface classes plentifully.
I think you need to see value in using an interface before using it. I think the design approach is, oh we have a class therefore we should have an abstract class and therefore we should have interfaces.
Firstly why do you need an interface, secondly why do you have an abstract class. It seems she may be adding things, for adding things sake. There needs to be clear value in the solution otherwise you are talking about code that has no value.
Emperically there you should see the value in her solution. If there is no value the solution is wrong, if it cant be explained to you she does not understand why she is doing it.
Simple code is the better solution and refactor when you need the complexity, flexibility or whatever perceived value she is getting from the solution.
Show the value or delete the code!
Oh one more thing have a look at the Java library code. Does that use the abstract / interface pattern that she is applying .. NO!

Grouping Related Constants Shared Between Classes

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:)

Categories