Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring a method with too many bool in it

I have this method in c#, and I wish to refactor it. There are just too many bools and lines. What would be the best refactoring. Making a new class seems a bit overkill, and cutting simply in two seems hard. Any insight or pointer would be appreciated.

method to refactor

    private DialogResult CheckForSireRestrictionInSubGroup(bool deletingGroup,string currentId)
    {
        DialogResult result = DialogResult.No;
        if (!searchAllSireList)
        {
            DataAccessDialog dlg = BeginWaitMessage();
            bool isClose = false;
            try
            {
                ArrayList deletedSire = new ArrayList();
                ISireGroupBE sireGroupBE = sireController.FindSireGroupSearch();

                if (sireGroupBE != null)
                {
                    //if the current group is in fact the seach group before saving
                    bool currentGroupIsSeachGroup = sireGroupBE.TheSireGroup.id == currentId; 

                    //if we have setting this group as search group
                    bool selectedAsSearchGroup = this.chkBoxSelectedSireGroup.Checked;

                    //if the group we currently are in is not longer the seach group(chk box was unchecked)
                    bool wasSearchGroup = currentGroupIsSeachGroup && !selectedAsSearchGroup;

                    //if the group is becoming the search group
                    bool becomesSearchGroup = !currentGroupIsSeachGroup && selectedAsSearchGroup;

                    //if the group being deleted is in fact the search group
                    bool deletingSearchGroup = deletingGroup && currentGroupIsSeachGroup;

                    //if the user checked the checkbox but he's deleting it, not a so common case, but
                    //we shouldn't even consider to delete sire in this case
                    bool deletingTemporarySearchGroup = deletingGroup && !currentGroupIsSeachGroup;         

                    //if we are not deleting a temporary search group and it's either
                    //becoming one (without deleting it) or we already are the search group
                    bool canDeleteSires = !deletingTemporarySearchGroup && 
                                          (becomesSearchGroup || currentGroupIsSeachGroup);
                    //we only delete sires if we are in search group
                    if (canDeleteSires)
                    {   
                        if (deletingSearchGroup || wasSearchGroup)
                        {
                            // If we deleted all sires
                            deletedSire = new ArrayList();
                            deletedSire.AddRange( sireGroupBE.SireList);
                        }
                        else
                        {
                            //if we delete a few sire from the change of search group
                            deletedSire = GetDeleteSire(sireGroupBE.SireList);
                        }
                    }

                    EndWaitMessage(dlg);
                    isClose = true;
                    result =  ShowSubGroupAffected(deletedSire);
                }
            }
            finally
            {
                if (!isClose)
                {
                    EndWaitMessage(dlg);
                }
            }
        }

        return result;
    }
like image 690
Xavier Avatar asked Jan 13 '12 14:01

Xavier


1 Answers

One option is to refactor out each of the primary booleans (canDeleteSires, deletingSearchGroup || wasSearchGroup) into methods with names that describe the readable version of the logic:

if (WeAreInSearchGroup())
{
    if (WeAreDeletingAllSires())
    {
        deletedSire = new ArrayList();
        deletedSire.AddRange( sireGroupBE.SireList);
    }
    else
    {
        deletedSire = GetDeleteSire(sireGroupBE.SireList);
    }
}

You then encapsulate your current boolean logic inside these methods, how you pass state (method arguments or class members) is a matter of taste.

This will remove the booleans from the main method into smaller methods that ask and answer a question directly. I've seen this approach used in the "comments are evil" style of development. To be honest, I find this a little overkill if you are a lone-wolf, but in a team it can be much easier to read.

Out of personal preference I would also invert your first if statement to return early, this will reduce the indentation level of the entire method:

if (searchAllSireList)
{
    return result;
}

DataAccessDialog dlg = BeginWaitMessage();
bool isClose = false;
try
...

But then you might get chastised by the "multiple returns are evil" crowd. I get the impression development practice is like politics...

like image 104
Adam Houldsworth Avatar answered Nov 10 '22 16:11

Adam Houldsworth