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);
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));