Java – Is it strange for a Builder object to have getter methods

builder-patterndesign-patternsjava

I have a fairly complex immutable data type that I'm using a builder object to instantiate. Currently, I have a setup where I parse a file, setting various fields in my builder, and then build the object. However, the files I'm using are error-prone, so I want to do some verification on my unbuilt objects first. And it's important to note that I don't want to throw an exception if an object doesn't pass verification, as that doesn't mean it's invalid, just incorrect.

The way I'm accustomed to seeing builders, though, is that they're "write-only". For example, Guava's ImmutableList.Builder class does not allow you to view the data you've submitted to it, leading me to use ArrayLists as a builder on the occasion that I need to edit the data before freezing it.

Alternatively, I suppose I could just go ahead and build my objects with errors in them, then create a new builder pre-loaded with the data of the built object, inspect the data, edit, and rebuild. This seems wasteful and inelegant, though.

Is it considered a code smell to put getter methods on your builder objects? Intuitively, it does seem a little strange to me, but more than once I've been faced with this type of problem, which often prompts me to keep an accessible copy of some of the data I'm passing to the builder so I can look at it later. Simply having a getter would make things easier.

Best Answer

I think there is nothing wrong per se to have getters in your builder class allowing to inspect which data was passed in. As Robert Harvey stated, getters are not part of the pattern, but sometimes a pragmatic solution is better than sticking to some doctrine. And there is not "the one and only correct way" to implement a pattern, design patterns always give you some degrees of freedom how to implement them.

However, you should be careful not to assign too many different responsibilities to that one class (and if a builder class has getters, this might be an indication for this). If your builder starts to become a repository for the input data, a validator for the data and the builder itself, then it has too many responsibilities, and you should consider to split it up into different classes.

Related Topic