I agree that you should go with what makes more sense semantically, but I also find that, when the boolean argument is optional, the thing that fairly often makes more sense when omitting it is for it to have a default value of false
- in languages that initialize instances of primitive types, false
is generally the default value for a boolean.
It then acts as an "on" flag for the less commonly used feature. So that you have:
DoSomething(someParams);
DoSomething(someParams, true);
// Or, if your language supports named parameters
DoSomething(someParams, optionalFeature: true);
So, I would have a slight bias for the parameter to default to false
, unless doing so feels unnatural (as in, it feels unnatural as a sentence when you read it). Sometimes, the exceptional behavior is better conceptualized as turning something off (for example, setters that take a boolean argument are often constructed this way, see Joop Eggen's answer; however, you should strive for encapsulation, and minimize the use of getters and setters).
If the feature controlled by the boolean argument is not less commonly used (in the general case), I wouldn't make it optional. Design for the general case. If there's a small number of users with applications that mostly use one value for the argument, they can create their own wrapper.
As for the logic inside the method, if it turns out that your choice makes it awkward to write conditionals, just introduce a new well-named variable with the flipped value (or a new variable that summarizes several boolean checks that repeat, or whatever) - it's not going to be a problem if your method is fairly short (which it should be - you shouldn't have a sprawling tree of nested if-statements in there).