myfn(string go, string for, string foo) {
possiblyDoStuff(go, foo);
possiblyDoOtherStuff(go, for);
possiblyDoOtherOtherStuff(for, foo);
someOtherFn(go, for, foo);
}
Now you have the 7 tests. 2 for each possibly = 6 which are pretty easy and 1 for myfn. It is exceedingly rare that functions require this kind of attention. There are usually a bunch of side effects or return values that are dependent on these checks. eg:
myfn(string go, string for, string foo) {
// examples of why you are calling these, to get vals
var go2 = possiblyDoStuff(go, foo);
var for2 = possiblyDoOtherStuff(go, for);
var foo2 = possiblyDoOtherOtherStuff(for, foo);
return { go2, for2, foo2 };
//move this to caller someOtherFn(myfn(go, for, foo));
}
When a function has has more than 2 if statements, you definitely want to break it up.
Imagine the function where conditions aren't related at all, as you posited:
What's really happening here? Why is all this wrapped in 1 function, when the args aren't related at all, nor the work they are dependent on?Let's say the caller was doing: myfn(1,2,foo);
I would split this function into 3 different function calls in the caller...
Let's use something that you wouldn't simply refactor upstream: Move that complexity into smaller chunks: Now you have the 7 tests. 2 for each possibly = 6 which are pretty easy and 1 for myfn. It is exceedingly rare that functions require this kind of attention. There are usually a bunch of side effects or return values that are dependent on these checks. eg: