I'm working on an application which writes on a NoSQL database (Elasticsearch to be precise) and I have to manage more than a dozen (the number grows with time) different document classes, that is classes with numerous fields, their getters and setters and methods to convert the class to a JSONObject (each field is annotated with @JsonProperty(PROPERTY_NAME)
and we use a JSON parser ).
All these classes have some fields and methods in common, which are all contained in a superclass (let us call it DocZero
) but they all have their own custom fields, which brings me to the point.
It is true that these fields are custom, but some are shared between different classes in a non-linear way, that is I have my document classes Doc1
, ... DocN
and I have some sets of fields (around 10 as of right now) shared by them in a very wild way.
Some examples to best convey the situation:Doc1
contains Set1
to Set5
;Doc2
contains Set1
, Set2
and Set5
to Set8
;Doc3
contains Set6
and Set7
;Doc4
contains Set5
and Set7
;Doc5
contains Set1
, Set2
, Set5
and Set7
to Set10
.
Given that I need to get and set these fields and, from time to time, manipulate a document with them, I made interfaces out of the Set#
, each containing (abstract) setters and getters.
As such, when I declare a class
public class DocX implements SetA, SetB, SetC
I get reminded to implement the methods and hence add the required fields, but this means that all the classes implementing the same set will need to have the same parameters and the same methods which means that I need to write the same code many times (sometimes more than getter and setter methods).
Adding all the fields to DocZero
foregoing the different Doc#
classes is a solution which I am not keen on using, since I prefer to distinguish different document types and since this situation is present, in lower magnitude, in another section of the code, with AnotherDocZero
, AnotherDoc#
and AnotherSet#
for which merging cannot be done due to other constraints and for which I would like a potential solution to work too.
I feel like this is one of those situation where multiple inheritance would solve the issue, but unfortunately Java doesn't allow it.
How could I avoid duplication in a situation like this? Have you got any advice to improve my handling of this issue?
I strongly suggest to keep your data classes simple even if it does mean that you will need to repeat many fields definitions - POJOs are definitely easier to maintain and understand how the "result" data object looks like if you have all fields in one place - multilevel inheritance will quickly create a mess
For constraints of having proper getters you should use interfaces as you do. You can even create single interface for every getter and group them in another one like
public interface Set1To5 extends Set1, Set2, Set3, Set4, Set5 {}
For avoid duplication of getters/setters you can use some additional lib like lombok or consider not using getters/setters at all (just make all the fields in your data document classes public
- but this one of course is not the option if you need to constraint classes with interfaces)
If several kinds of fields are often grouped together, that suggests that grouping is a natural part of the domain of your program, and should be represented as such.
So, if you often find this in your classes
int xCoordinate;
int yCoordinate;
You should instead introduce
public final class Point ... {
private final int x;
private final int y;
Point(int x, int y) {
...
}
...
}
then instead of repeating x
and y
, write
Point position;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With