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;
}
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With