3 ms·
If all the functions need state from all the other functions, that is the problem a class or a struct solves - e.g. a place to store shared state. If the 7 thi
by spicyusername 2y ago
If all the functions need state from all the other functions, that is the problem a class or a struct solves - e.g. a place to store shared state.
If the 7 things are directly related to one another and are _really_ not atomic things (e.g. "Find first user email", "Filter unknown hostnames", etc), then they can be in a big pile in their own place, but that is typically pretty rare.
In general, you really want to let the code be crisp enough and your function names be intuitive enough that you don't need comments. If you have comments above little blocks of code like "Get user name and reorder list", that should probably just go into its own function.
Typically I build my code in "layers" or "levels". The lowest level is a gigantic pile of utility functions. The top level is the highest level abstractions of whatever framework or interface I'm building. In the middle are all the abstractions I needed to build to bridge the two, typically programs are between 2-4 layers deep. Each layer should have all the same semantics of everything else at that layer, and lower layers should be less abstract than higher layers.
- fragmede 2y agoMy problem with the class/struct approach is it doesn't work if you don't need everything everywhere. foo(...): f1(a,b,c,d,e,f) f2(a,c,d,f) f3(b,c,d,e) ... f7(d,e) But with long descriptive variable names that you'd actually use so the function calls don't fit on one line. Better imo to have a big long function instead of a class and passing around extra variables. Though, ideally there isn't this problem in the first place/it's refactored away (if possible).
- psychoslave 2y agoA function that needs so many parameters is already a no go. If it doesn't return anything, then it's either a method in a class, or it's a thing that perform some tricky side effect that will be better completely removed with a more sound design.
- vanviegen 2y agoCreating a class around the too many arguments you want to pass to your function may be a good idea if the concept happens to be coherent and hopefully a bit more long-lived than just the function call. Otherwise, your just hiding the fact that your function requires too many arguments by calling them properties.
- psychoslave 2y agoWell, if there is no class that seems to make sense to group them, that's an additional flag that points to additional thoughts on design. Or discussion with fellow developer about it. Of course, on some very exceptional case, 7 arguments might be relevant after all. If that is like the single one in the code base, and after thorough discussion with everyone implicated in the maintenance of the code it was agreed as an exceptionally acceptable trade-off for some reasons, making sure this would not leak in all the code base as it's called almost everywhere, then let it be. But if it's a generalized style through the whole codebase, there are obvious lake of care for maintenability of the work and the team is going to pay for that sooner than later.
- RaftPeople 2y ago> A function that needs so many parameters is already a no go. This rule is the same as lines of code type rules. The number itself is not the issue, it could be few parameters and a problem or it could be many parameters and not be an issue at all.
- edflsafoiewq 2y agoIt works fine. Not all the methods need to use all the struct members.
- spicyusername 2y agoYou access the shared data via the struct / class reference, not as method parameters. That's the benefit. e.g. foo(...): # Fields a b c d e # Methods f1(f) f2(f) f3() ... f7()
- mckn1ght 2y agoMoving them to a higher scope makes it harder to change anything in foo. Now anytime you want to read or write a-e you have to build the context to understand their complete lifecycles. If all the logic were smooshed together, or if it were factored into the original functions with lots of parameters, as ugly as either of them might be, you still have much more assurance about when they are initialized and changed, and the possible scopes for those events are much more obviously constrained in the code.
- spicyusername 2y agoIf all those functions need all those variables, then you're either going to put them in a class, or put all those variables in something like a dict and just pass that in. Seeing 10 variables passed in to a function is a code smell. Whether you put in in a common class / struct or aggregate them in a dict depends on whether or not all those functions are related. In general, your functions should not be super duper long or super duper intended. Those are also code smells that indicate you have the wrong abstractions.