Having multiple Boolean method parameters is a really really evil thing to do. This is the ninth in a series of posts on Code Gardening - the practice of making small improvements as you see them while you are working.

In last weeks post we discussed how boolean parameters are evil and what can be done to rectify the issue.

But what do you do when the method in question has many boolean parameters?

Consider this method, reproducing something I found in a production system many years ago.

myGrid.ConfigureBehavior(true, true, false, false, true, false, true, true);

Makes perfect sense, right?

I found this code in a Windows.Forms based rich client application with well over 200 different uses of the grid across its many screens.

Perhaps seeing the method declaration would help …

public void ConfigureBehavior(
    bool multiSelect,
    bool drillDown,
    bool showCheckBoxes,
    bool autoSizeToWindow,
    bool fixFirstColumn,
    bool fixLastColumn,
    bool allowCopy,
    bool autoSizeColumns)
{
    // ...
}

Turning this in to two hundred and fifty six different methods would be absurd. (Actually, while it’s not relevant to discuss in this post, there wouldn’t be quite that many because some combinations don’t make any sense. Using checkboxes requires multiple selection; auto sizing to the window precludes auto sizing to columns, and so on.)

Fortunately, there is a better way - we can turn all of these options into a single Enum.

[Flags]
public enum GridOptions
{
    None = 0,
    MultiSelect = 0x1,
    DrillDown = 0x2,
    ShowCheckBoxes = 0x4,
    AutoSizeToWindow = 0x8,
    FixFirstColumn = 0x10
    FixLastColumn = 0x20,
    AllowCopy = 0x40, 
    AutoSizeColumns = 0x80    
}

Aside: Using hex codes to assign values for the enumeration makes the use of bit patterns clear. For more about the use of [Flags], see this stackoverflow answer.

Our method declaration now becomes:

public void ConfigureBehavior(GridOptions options)
{
    // ...
}

Better yet, our call to this method becomes:

myGrid.ConfigureBehavior(
    GridOptions.MultiSelect 
    | GridOptions.DrillDown
    | GridOptions.FixFirstColumn
    | GridOptions.AllowCopy
    | GridOptions.AutoSizeColumns);

This is greatly more intelligible than the original.

We also have the advantage that adding a new option to the enumeration doesn’t require revisiting every single call across the entire application. And in the unlikely case that an option needed to be removed, the compiler would helpfully highlight anywhere it was still used - much cleaner than trying to remove the fifth boolean parameter from the original list and then trying to review every single use to see if it still made sense.

Comments

blog comments powered by Disqus