Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 249
James McMahon Avatar asked Jun 10 '11 15:06

James McMahon


2 Answers

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.

like image 153
Vivin Paliath Avatar answered Nov 15 '22 05:11

Vivin Paliath


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.

like image 30
Peter Lawrey Avatar answered Nov 15 '22 05:11

Peter Lawrey