Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring an If else tree

I have an if else tree that is going to grow as I add additional items for it to maintain and I'm looking at the best way to write it for maintainability I'm starting with this code

private void ControlSelect()
{

    if (PostingType == PostingTypes.Loads && !IsMultiPost)
    {
        singleLoadControl.Visible = true;
          singleTruckControl.Visible = false;
          multiTruckControl.Visible = false;
          multiLoadControl.Visible = false;
    }
    else if (PostingType == PostingTypes.Trucks && !IsMultiPost)
    {
        singleLoadControl.Visible = false;
          singleTruckControl.Visible = true;
          multiTruckControl.Visible = false;
          multiLoadControl.Visible = false;
    }
    else if (PostingType == PostingTypes.Loads && IsMultiPost)
    {
        singleLoadControl.Visible = false;
          singleTruckControl.Visible = false;
          multiTruckControl.Visible = false;
          multiLoadControl.Visible = true;
    }
    else if (PostingType == PostingTypes.Trucks && IsMultiPost)
    {
        singleLoadControl.Visible = false;
        singleTruckControl.Visible = false;
          multiTruckControl.Visible = true;
        multiLoadControl.Visible = false;
    }
}

and thinking of re-factoring it to something like this

private void ControlSelect()
{
    List<UserControl> controlList = GetControlList();

      string visableControl = singleLoadControl.ID;
      if (PostingType == PostingTypes.Loads && !IsMultiPost)
      {
        visableControl = singleLoadControl.ID;
      }
      else if (PostingType == PostingTypes.Trucks && !IsMultiPost)
      {
        visableControl = singleTruckControl.ID;
      }
      else if (PostingType == PostingTypes.Loads && IsMultiPost)
      {
        visableControl = multiLoadControl.ID;
      }
      else if (PostingType == PostingTypes.Trucks && IsMultiPost)
      {
        visableControl = multiTruckControl.ID;
      }

      foreach (UserControl userControl in controlList)
      {
        userControl.Visible = (userControl.ID == visableControl);
      }
}

private List<UserControl> GetControlList()
{
    List<UserControl> controlList = new List<UserControl>
      {
        singleLoadControl,
            multiTruckControl,
            singleTruckControl,
            multiLoadControl
      };
      return controlList;
}

I take a performance hit but I can manage all of my controls is a single place

my other thought was to make each selected control block it own method, something like this

private void SetSingleLoadControlAsSelected()
{
      singleLoadControl.Visible = true;
      singleTruckControl.Visible = false;
      multiTruckControl.Visible = false;
      multiLoadControl.Visible = false;
}

I don't take a performance hit but I'm maintaining the controls in multiple location

I'm leaning for option one just because I like maintainability aspect of it.

like image 830
Bob The Janitor Avatar asked Sep 03 '09 17:09

Bob The Janitor


2 Answers

what about

singleLoadControl.Visible  = 
      PostingType == PostingTypes.Loads  && !IsMultiPost;      
singleTruckControl.Visible = 
      PostingType == PostingTypes.Trucks && !IsMultiPost;      
multiTruckControl.Visible  = 
      PostingType == PostingTypes.Loads  && IsMultiPost;      
multiLoadControl.Visible   =  
      PostingType == PostingTypes.Trucks && IsMultiPost;

if you want capability to make multiple controls visible (or add more enumerated values) decorate the enum with [Flags] attribute as follows:

[Flags]   
public enum PostTyp { None=0, IsMultiPost = 1, Loads = 2, Trucks = 4 }

and modify Code as follows:

singleLoadControl.Visible  = 
      ((PostingType &  (PostTyp.Loads | ~PostTyp.MultiCast)) 
         == PostingType );      
singleTruckControl.Visible = 
      ((PostingType & (PostTyp.Trucks | ~PostTyp.MultiCast)) 
         == PostingType );          
multiTruckControl.Visible  = 
      ((PostingType & (PostTyp.Loads  |  PostTyp.MultiCast)) 
         == PostingType );        
multiLoadControl.Visible   =  
      ((PostingType & (PostTyp.Trucks |  PostTyp.MultiCast)) 
         == PostingType );      
like image 138
Charles Bretana Avatar answered Oct 03 '22 08:10

Charles Bretana


As you appear to be using an enumeration, I would recommend a switch with a default case to cope with unknown values. I believe this approach makes intentions clearer than doing all the checking in the assignment.

switch (PostingType)
{
case PostingTypes.Loads:
   singleLoadControl.Visible = !IsMultiPost;
   multiTruckControl.Visible = IsMultiPost;
   singleTruckControl.Visible = false;
   multiTruckLoadControl.Visible = false;
   break;

case PostingTypes.Trucks:
   singleLoadControl.Visible = false;
   multiTruckControl.Visible = false;
   singleTruckControl.Visible = !IsMultiPost;
   multiLoadControl.Visible = IsMultiPost;
   break;

default:
   throw InvalidOperationException("Unknown enumeration value.");
}
like image 38
Jeff Yates Avatar answered Oct 03 '22 08:10

Jeff Yates