Search code examples
c#business-logicbusiness-rules

Code improvements for implementing business logic


I had asked this question previously on SO. This is related to it. We have code base similar to this:

IRecipie FindRecipiesYouCanMake(IEnumerable<Ingredientes> stuff, Cook cook)
{
 if(stuff.Any(s=>s.Eggs && s.Flour) && cook.DinerCook)
 {
  if(s=>s.Sugar)
   return new Pancake("Yum");
  if(s=>s.Salt)
   return new Omlette("Yay");
 }
 /*.....
 ......
 .....
 loads of ifs and buts and else*/
}

I want to get rid of this mess and take a more data structure and OO route. Even the code sample i have provided is not as horrendous as it is. I looked at the specification pattern and found it applicable. Any ideas how to improve the code.

EDIT: Now that I realize it, I might even like to implement a method of this signature:

List<IRecipe> WhatAllCanBeCooked(IEnumerable<Ingredients> stuff, Cook cook);

Solution

  • I would delegate this logic to the individual IRecipie classes:

    if (Pancake.CanBeMadeBy(stuff, cook)) {
        return new Pancake("Yum");
    }
    ....
    
    
    public class Pancake: IRecipe {
        ...
        public static bool CanBeMadeBy(IEnumerable<Ingredientes> stuff, Cook cook) {
            return stuff.Any(s=>s.Eggs && s.Flour && s.Sugar) && cook.DinerCook;
        }
    
    }
    

    Edit in response to comment

    To find all the recipes that can be cooked, just do something like this:

    List<IRecipe> results = new List<IRecipe>();
    
    if (Pancake.CanBeMadeBy(stuff, cook)) {
        results.Add(new Pancake("Yum");
    }
    ....
    

    Edit 2 Alternatively, if you store a list of all possible recipes somewhere, you can turn CanBeMadeBy into an instance method instead of a static, and do this:

    List<IRecipe> allRecipes = // all possible recipes
    ...
    return allRecipes.Where(r => r.CanBeMadeBy(stuff, cook));