3 ms·
If you find yourself passing in flags to change behavior, it sounds like you should just have two functions. For other cases, an enum might serve your needs bet
by jef_leppard 4y ago
If you find yourself passing in flags to change behavior, it sounds like you should just have two functions. For other cases, an enum might serve your needs better as it gives you more options as your codebase grows. That said, I wouldn't call boolean flags a _smell_. Seems like throwing out the baby with the bath water if you ask me.
- amelius 4y agoYeah, it's either flags or duplicating code. Both are smelly, so pick your poison.
- jackblemming 4y agoNo? Both separate functions can call a 3rd shared function if they want. You can also restructure the code with dependency injection. There's plenty of options that don't require duplication
- jef_leppard 4y agoYep. You said it better than I could. There are a lot better ways to do control flow than passing in a flag. Inversion of control being another great example.
- amelius 4y agoAlas, in reality the code controlled by the flag is often mixed with other code and separating the two is often difficult to do right, e.g. requiring to pass a lot of data hence and forth.
- gentleman11 4y agoThat indirection can end up a bit fractal. Sometimes the duplication is less bad than the readability reduction. You have to trust your intuition at those times
- tbrownaw 4y agoDuplication is for when future changes are independent. "This client wants their reports customized" maybe. Flags are for when future changes affect both options. "On top of the usual functionality, we can also optionally handle this other related thing" or so. Or --dry-run handling.
- jef_leppard 4y agoEh maybe. Theres no hard and fast rules in this business for sure but when I'm dealing with pure business logic, if I am passing flags in that make the function behave in more than one way, I'll try my damndest to refactor until there is one and only one thing that that function does. If I _had_ to pass in a flag, then I'd make a top level function that mostly did flow control and called into functions that had straight line logic paths. Something like this (using enums instead of booleans): function doTheThing({typeOfThing, ...rest}) { if (typeOfThing === Thing.FOO) { doThingWithFoo(rest) } if (typeOfThing === Thing.BAR) { doThingWithBar(rest) } }