-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Refactor FieldCapabilities creation by adding a proper builder object #121310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor FieldCapabilities creation by adding a proper builder object #121310
Conversation
|
Pinging @elastic/es-search-foundations (Team:Search Foundations) |
c87de3e to
09f5c33
Compare
09f5c33 to
085ae87
Compare
| assertThat(fooRankField, Matchers.hasKey("rank_feature")); | ||
| assertEquals( | ||
| new FieldCapabilities("fooRank", "rank_feature", false, true, false, null, null, null, Collections.emptyMap()), | ||
| new FieldCapabilitiesBuilder("fooRank", "rank_feature").isAggregatable(false).build(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't you use the fieldCapabilities method to create a builder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch! Done.
| return this; | ||
| } | ||
|
|
||
| public FieldCapabilitiesBuilder indices(String... indices) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class is used only for testing, but this could be used in the main code in the future. Should we have defensive copies of the indices passed as parameters to avoid mutating the array content?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| this.isSearchable = true; | ||
| this.isAggregatable = true; | ||
|
|
||
| this.meta = Map.of(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the use of Collections.emptyMap() is more appropriate for creating an immutable empty map in the consturctor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
|
||
| private Map<String, Set<String>> meta; | ||
|
|
||
| public FieldCapabilitiesBuilder(String name, String type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name and type look like required fields. Should any validation be applied?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What kind of validation did you have in mind? No piece of code validates these anywhere in the AFAICT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is minor; I was thinking of checking for nullity. I believe the @NotNull annotation should be enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this annotation is very rarely used in the code base, and since IMHO everything is not nullable by default, unless explicitly marked as @Nullable, let's keep it as it is.
| return this; | ||
| } | ||
|
|
||
| public FieldCapabilitiesBuilder meta(Map<String, Set<String>> meta) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As previously, should the map be copied?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| type, | ||
| new FieldCapabilities(field, type, isMetadataField, true, isAggregatable, null, null, null, Collections.emptyMap()) | ||
| new FieldCapabilitiesBuilder(field, type).isMetadataField(isMetadataField) | ||
| .isSearchable(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is optional
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
| ) | ||
| ); | ||
| multi.put("long", new FieldCapabilitiesBuilder(fieldName, "long").indices("one-index").build()); | ||
| multi.put("text", new FieldCapabilitiesBuilder(fieldName, "text").indices("another-index").build()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the method be called isAggregatable(false) in the builder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Done.
|
Thank you, @GalLalouche, for working on this. The readability of the code has been increased, avoiding the 'telescoping constructor' annoying issue. I've left some minor comments to address. |
25ab4b5 to
3211c62
Compare
9767d5f to
cbc52e5
Compare
cbc52e5 to
d5bd523
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you @GalLalouche for this update
…elastic#121310) Reduce boilerplate associated with creating `FieldCapabilities` instances. Since it's a class with a huge number of fields, it makes sense to define a builder object, as that can also help with all the Boolean and null blindness going on. Note while there is a static Builder class in `FieldCapabilities`, it is not a proper builder object (no setters, still need to pass a lot of otherwise default parameters) and also package-private. To avoid changing that, I defined a new `FieldCapabilitiesBuilder` class. I also went over the code and refactored places which used the old constructor.
Reduce boilerplate associated with creating
FieldCapabilitiesinstances.Since it's a class with a huge number of fields, it makes sense to define a builder object, as that can also help with all the Boolean and
nullblindness going on.Note while there is a static
Builderclass inFieldCapabilities, it is not a proper builder object (no setters, still need to pass a lot of otherwise default parameters) and also package-private. To avoid changing that, I defined a newFieldCapabilitiesBuilderclass. I also went over the code and refactored places which used the old constructor.