I have a couple of simple classes that implement the Null Object pattern.
To illustrate the hierarchy, let's define a Config
interface with two classes implementing it ConfigItem
and MissingConfig
, each defined in its own file.
// Config.java
public interface Config {
Something process();
}
// ConfigItem .java
public class ConfigItem implements Config {
// some fields
@Override
public Something process() {
// some actual logic and return statement
}
}
// MissingConfig.java
public enum MissingConfig implements Config {
INSTANCE;
@Override
public Something process() {
// do no harm
}
}
In my case, the MissingConfig
object is immutable and only a single instance is guaranteed to exist.
This works fine and allows me to avoid null-checks. However, the fact that this implementation of the Config
interface exists can be missed by other developers working with the code.
I'm trying to find a way to make the reusable null-representation of the Config
easy to find.
It occurred to me that I could expose it using the interface itself:
public interface Config {
Something process();
MISSING = MissingConfig.INSTANCE;
}
so that it would auto-complete for everyone trying to do something with Config
This, however, in a way, introduces a constant in the interface, which is advised against in Joshua Bloch's Effective Java (Chapter 4, item 19)
Another way to structure the code that occurred to me is to define the enum inside the interface.
public interface Config {
Something process();
public enum Missing implements Config {
INSTANCE;
@Override
public Something process() {
// do no harm
}
}
}
This looks almost as readable when consumed
Config.Missing.INSTANCE
but not as nice as the previous version... and technically, this is still a constant defined inside an interface. Just a bit more convoluted.
Is there any way I can make the consumption of the null-object blatantly obvious without violating the good practices of interface design... or am I trying to have my cake and eat it too?
I'm beginning to think my original implementation (with the enum defined in its own file) is the most elegant one and that the discoverability should be achieved by an explicit mention of it in the Javadoc. As much as I'd love to, I can't protect myself against people who don't read javadocs.
I have also thought about switching from an interface
to an abstract class
but that limits reuse in ways I cannot accept due to single inheritance (some existing code that has to do with the Config
)
Hope this isn't too open-ended for Programmers