At work we have an interface that is getting bloated. The interface is designed to be easily implemented by an immutable object. So it looks something like this:
//there is no behavior here, just data access
interface DataBlock {
String name();
Integer idNumber();
Double score();
Instant time();
//...12 additional methods with arbitrary return types
}
There are several places in the code where it would be useful to represent the values inside the DataBlock as a Map. For example, when implementing a Builder or Factory.
My initial question was: What should the generic type of the map be?
Keying on interface method names yielded: Map<String, Object> dataBlockAsMap = Data
. I didn't like this option because it's easy to mistype the method name. For example, It will fail silently if anyone writes map.get("iDNumber")
instead of map.get("idNumber")
.
I am currently leaning toward Map<DataBlockField, Object>
were DataBlockField
is an enum with one type for each method in the interface. The upside of this approach is (1) each enum value can "know" its required type, and (2) it makes it easy to write batch operations like:
public static Map<DataBlockField, Object> asMap(DataBlock block) {
Map<DataBlockField, Object> map = new HashMap<>();
for(DataBlockField field : DataBlockField.values()) {
//enum helps extract a value from datablock
map.put(field, field.getFrom(block));
}
}
//and
public static String toString(DataBlock block) {
StringBuilder sb = new StringBuilder();
for(DataBlockField field : DataBlockField.values()) {
//enum helps extract a value from datablock
sb.append(field.getFrom(block));
}
}
My question is: Is introducing this "Interface backed enum" a good idea? I ask because I might be missing something. On the surface this "interface backed enum" is vaguely similar to the Builder Pattern. However, I see Builders left and right. Yet I have never seen an enum written to mirror the methods in an interface.
Am I missing something here?
DataBlock
first ?