I recently run into the following situation.
class A{
public:
void calculate(T inputs);
}
Firstly, A
represents an object in the physical world, which is a strong argument for not splitting the class up. Now, calculate()
turns out to be quite a long and complicated function. I perceive three possible structures for it:
- write it as a wall of text - advantages - all the information is in one place
- write
private
utility functions in the class and use them incalculate
's body - disadvantages - the rest of the class doesn't know/care/understand about those methods write
calculate
the following way:void A::calculate(T inputs){ auto lambda1 = () [] {}; auto lambda2 = () [] {}; auto lambda3 = () [] {}; lambda1(inputs.first_logical_chunk); lambda2(inputs.second_logical_chunk); lambda3(inputs.third_logical_chunk); }
Can this be considered a good or bad practice? Does this approach reveal any problems? All in all, should I consider this as a good approach when I am again faced with the same situation?
EDIT:
class A{
...
public:
// Reconfiguration of the algorithm.
void set_colour(double colour);
void set_density(double density);
void set_predelay(unsigned long microseconds);
void set_reverb_time(double reverb_time, double room_size);
void set_drywet(double left, double right);
void set_room_size(double value);;
private:
// Sub-model objects.
...
}
All those methods:
- get a value
- compute some other values, without using state
- call some of the "sub-model objects" to change their state.
It turns out that, excepting set_room_size()
, those methods simply pass the requested value to sub-objects. set_room_size()
, on the other hand, does a couple of screens of obscure formulas and then (2)does half a screen of calling sub-objects setters to apply the various obtained results. Therefore, I have separated the function into two lambdas and call them at the end of the function. Had I been able to split it into more logical chunks, I would have isolated more lambdas.
Regardless, the goal of the current question is to determine if that way of thinking should persist, or is it at best not adding value (readability, maintainability, debug-ability etc.).
Firstly, A represents an object in the physical world, which is a strong argument for not splitting the class up.
SurelyA
represents data about an object that could exist in the physical world. You can have an instance ofA
without the real object and a real object without an instance ofA
, so treating them like they're one and the same is nonsensical.calculate()
will know about those sub-functions.A
, that's taking it a bit to the extreme.A
represents an object in the physical world, which is a strong argument for not splitting the class up." I was, unfortunately, told this when I started programming. It took me years to realize that it's a bunch of horse hockey. It's a terrible reason to group things. I can't articulate what are good reasons to group things (at least to my satisfaction), but that one is one you should discard right now. The end all, be all of "good code" is that it works right, is relatively easy to understand, and is relatively easy to change (i.e., changes don't have weird side effects).