Search code examples
javadatabasejava-8code-duplication

Avoid duplicate code with numerous Java classes sharing fields


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?


Solution

  • 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;