Hank Mooody
Hank Mooody

Reputation: 527

Refactoring business logic with if and severals else if

I have method that returns list of employee positions List<string> listPositions. If method returns only one string basic logic would be something like this:

if (listPositions.Contains("Admin"))
{
   // business logic 1,for example Console.WriteLine("I'm Admin");
}
else if (listPositions.Contains("OfficeDirector"))
{
  //business logic 2
}
else if (listPositions.Contains("Regular") || listPositions.Contains("HumanResource"))
{
  //business logic 3
}

Now, method can return more than one string, so employee can be Admin and Office Director for example.Now I need to combine implementation in first if and first else if and I don't want to get lost inside several if-statements, so I'm asking you if there is more elegant solution to this problem . Thank you.

Upvotes: 0

Views: 173

Answers (3)

Grzegorz
Grzegorz

Reputation: 74

You can define Dictionary<string, Action> or Dictionary<string, Func> like

Dictionary<string, Action> actions = new Dictionary<string, Action>
{
  { "Admin", new Action(() => Console.WriteLine("I'm Admin")) },
  { "OfficeDirector", new Action(() => Console.WriteLine("I'm OfficeDirector")) },
  { "Regular", new Action(() => Console.WriteLine("I'm Regular or HumanResource")) },
  { "HumanResource", new Action(() => Console.WriteLine("I'm Regular or HumanResource")) },
};

and then simply call the logic:

foreach(var position in listPositions) {
  if (actions.ContainsKey(position)) {
    actions[position]();
  }
}

Edit: Or use as a key Predicate<string>, bit more complicated example:

static Dictionary<Predicate<string>, Action> PredicatedActions = new Dictionary<Predicate<string>, Action>()
{
  { p => p == "Admin", new Action(() => Console.WriteLine("I'm Admin")) },
  { p => p == "OfficeDirector", new Action(() => Console.WriteLine("I'm OfficeDirector")) },
  { p => p == "HumanResource" || p == "Regular", new Action(() => Console.WriteLine("I'm Regular or HumanResource")) }
};

then just call applicable actions:

var actionToExecute = listPositions.SelectMany(
  position => PredicatedActions.Keys.Where(condition => condition(position)).Select(key => PredicatedActions[key])
).Distinct();

actionToExecute.ToList().ForEach(action => action());

Upvotes: 2

cristobalito
cristobalito

Reputation: 4282

What you want to use here is a strategy pattern. The seminal text on this is the Gang Of Four book by Gamma et. al. If you are new to design patterns, Head First Design Patterns may be more accessible. Plenty of websites and other resources discuss the pattern. I highly recommend you check it out and the other design patterns discussed in these resources.

Upvotes: 1

Bassie
Bassie

Reputation: 10390

You could use a switch statement, I find them a lot easier to read.

Or, rather than using if / else, if / else, just have a bunch of if statements in a row. These can then catch the valid positions:

if (listPositions.Contains("Admin"))
{
   // Concatenate some string or add to a list for final checking
}
if (listPositions.Contains("OfficeDirector"))
{
  // Concatenate some string or add to a list for final checking
}
if (listPositions.Contains("Regular") || listPositions.Contains("HumanResource"))
{
  // Concatenate some string or add to a list for final checking
}

Then have some check at the end for which positions the person holds, and apply all the relevant business logic.

Upvotes: 0

Related Questions