In a data cleaning application I have a series of methods each of which takes a custom object and returns it after some processing.
I am aware of design patterns which put each of these methods in its own class and chains them together, but I am not interested in splitting up this class. It is a few lines in the middle of one class embedded in a rather large Java monolith. For this same reason I am not going to include a single module from Scala or some other functional language for this small piece of code.
The methods must be implemented in the correct order because the logic of each depends on what has already been done. Thus I have given them new numbered names, and it is the order of this numbering I wish to preserve.
My code at the moment looks like this:
customObject = method1(customObject);
customObject = method2(customObject);
customObject = method3(customObject);
customObject = method4(customObject);
customObject = method5(customObject);
customObject = method6(customObject);
Is there a more fluent way to chain these together, without reversing their order as it appear in the code? In other words, I have dismissed the following as potentially misleading (the real method names would not show they are listed backwards):
customObject = method6(method5(method4(method3(method2(method1(customObject))))));
and
customObject = method6(customObject)
= method5(customObject)
= method4(customObject)
= method3(customObject)
= method2(customObject)
= method1(customObject);
(In any case, apart from reversing the order when read, the latter is not valid Java code, as the compiler requires a variable on the left hand side if there is a method call on the right)
It is a small question about a small piece of code. I suspect the answer is 'no' because of the way the processing in each line flows from right-to-left (into the method parameter, and assigned to the variable name on the left). But I can't rid myself of this nagging feeling I might be missing something in the language which will allow a more elegant chaining of these method calls. Perhaps this is something which Java cannot do.
You could use a fluent interface pattern. Something like this:
dataCleaner
.method1(customObject)
.method2(customObject)
.method3(customObject)
.method4(customObject)
.method5(customObject)
.method6(customObject)
Where each method on dataCleaner returns this
e.g.
public DataCleaner method1(CustomObject customObject) {
// do some cleaning ...
// ...
return this;
}
Notes:
This assumes that each method mutates customObject
in such a way that it is ready to be the input into the next method. Based on how you showed your current code, I think this assumption is valid. If this is not valid then you could make DataCleaner
stateful and share state between the discrete methods via a class member(s), something like this perhaps:
CustomObject clean = new DataCleaner(customObject)
.method1()
.method2()
.method3()
.method3()
.method5()
.method6()
.get();
It could be argued that the above approach is just method chaining rather than a formal fluent interface but it's possible that your actual implementation could return something or could have some methods which take additional context etc all of which would bring it closer to the canonical form of a fluent interface. And leaving aside the semantics of how to describe this pattern, it does at least allow you to tidy up your code and to express the dependencies between this chain of methods in a way which can be easily understood.