[DISCUSS] Code generation for commonly implemented basic methods
See original GitHub issueI recently found a bug in ArrayOfDoublesSketchAggregatorFactory .equals()
(fixed in https://github.com/apache/incubator-druid/pull/8326) which made me think that we may need a better way to implement and maintain them. equals()
, hashCode()
and toString()
are very commonly used functions and not easy to catch a mistake if ppl write them manually. To avoid mistakes, I usually use the code generation function of Intellij. This function is good but is not enough to automatically maintain those implementations on code changes.
The Lombok is a library to address this kind of use case. It can automatically generate codes of equals()
, hashCode()
, and toString()
at compile time so that we can expect the implementations are always up to date. Also, they are programmatically generated and it’s safer than human codes.
I also find the Lombok library useful when the builder pattern is useful. It provides an annotation called @Builder
which automatically generates a builder implementation for a class. This could be very useful to maintain the test codes for user-facing configuration classes. For example, I have added a couple of new configurations to ParallelIndexTuningConfig
which also required to fix all places calling the constructor of the class. With the builder, I think we can reduce the required changes which could reduce the PR size.
The downside of using a library such as Lombok is the build time might be longer since it needs to generate more source codes. But I still think it would be worth to take it.
If we go with this way, I think we can start with equals()
, hashCode()
and toString()
methods and gradually change those implementations with Lombok annotations (like 10 classes in each PR). Probably we need unit tests as well if those methods of a class only take account into only a subset of variables defined in that class.
Welcome any thoughts.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:5
- Comments:21 (18 by maintainers)
I would vote +2 for Lombok. People who haven’t used Lombok usually assume that it’s too much magic and that it makes it hard to debug. In my experience this has not been the case. Lombok makes it easy to delombok methods if you want to debug that piece through a single click in the IDE, and the methods are usually so simple and boilerplate that there really should be no bugs in it. I would trust automatically generated code that is tested by tons of people using it over manually added code by a developer who might miss a field in the equals or hashcode method.
Lombok also does take you to the right place when you step through the code (to the relevant Lombok annotation).
In fact, I find that Lombok makes debugging easier by reducing boilerplate in code so you don’t have to worry about it and makes the code much easier to understand and maintain.
Sorry, I was thinking to test out all those libraries we discussed here, but have never got to it. I quickly checked AutoValue, Immutables, and Lombok today, and it seems Lombok might suit our needs most because we often add more methods in the “value” classes which seems not possible in other libraries since they generate concrete classes based on the annotated interface (I quickly read the docs of them, so could be wrong). It might be arguable whether it’s a good practice or not, but that’s what we have now. Also, I remember wrong about the line number changes and Lombok doesn’t change the line number in stack trace. My other concern was about potentially slow response of the IDE but I think it could apply same for other libraries as well. I would vote for trying it out and seeing if there is any other issue.