I’m currently in the process of reworking a monolithic function.
My first step is finding blocks of code that can be extracted into their own “sub”-methods for ease of readability & maintainability.
One of the blocks is a loop that runs over a list of entities of type A
that contain a list of objects of type B
which in turn contains a list of objects of type C
, so
class B{
cList: C[];
}
class A {
bList: B[];
}
The purpose of the loop is to produce 3 results:
- result X: determine a
boolean
property for the instance of A based on the C’s contained in
A’s list of B where X istrue
if at least some of B contain the boolean property astrue
. - result Y: determine the name of B’s where the aforementioned boolean is true
- result Z: produce a list of all props of C that fulfill a specific condition.
For that a combined loop to determine all those properties together makes sense to me, as otherwise i would loop over the same sub-lists multiple times which seems kind of inefficient to me (especially since the code already exists, so I don’t have to introduce the premature optimiziation 😉 ).
So i moved the loop to it’s own method and just pass it the A.
But now, i have a choice to make about how to name this method:
- A: something like
extractXAndYAndZFromA
which seems overly specific and ugly but would be on-point, or - B:
extractBaseInfoFromA
which is way too broad.
I don’t like either one of those, but i also don’t want to break the method into 3 methods to then loop over the same things 3 times just to have one-purpose methods.
I’d really love to hear your opinions on this and how you would/did approach those (luxury) problems.
Kind Regards
1
You may need to overcome the “I don’t want to” attitude. Do it as an experiment! How else are you going to learn and gain new insights? If you find out that a separation of concerns makes the code unreadable or inefficient you can still go back.
Doing the enumeration three times might not be really inefficient, unless the enumeration overhead is significant in comparison to the actual processing. This may depend on total size, whether the data fits in memory, complexity of operations, etc, so the best way to determine this is to measure it.
Your X and Y are pretty closely related, so it might make sense to determine them in one loop. Z looks completely unrelated, so determining it in an unrelated loop seems to be reasonable.
If you use a language that supports iterators you might want to split the whole thing into an iterator that yields triples (a, b, c)
so your processing of the contained data can be separated from the task of walking the data structure. However, for a 3-level deep nested enumeration which may be basically done in 3 lines of code that might be copied one or two times this is probably not worth the effort.