Everyone has had good ideas, but since you're asking about OOP, I'd suggest refactoring it altogether.
void Main()
{
var formula = new Formula(new[] {
new Ingredient("Flour, AP", 100m, true),
new Ingredient("Water, Warm", 70.15m, false),
new Ingredient("Salt", 3.04m, false),
new Ingredient("Yeast", .24m, false),
new Ingredient("Pate fermentee", 2.53m, false)
});
var weights = formula.GetWeights(10000m);
}
class Ingredient
{
public string Name { get; private set; }
public decimal Percentage { get; private set; }
public bool IsFlour { get; private set; }
public Ingredient(string _Name, decimal _Percent, bool _IsFlour)
{
this.Name = _Name;
this.Percentage = _Percent;
this.IsFlour = _IsFlour;
}
}
class Formula
{
private IEnumerable<Ingredient> Ingredients { get; set; }
public decimal SumPercentages { get; private set; }
public Formula(IEnumerable<Ingredient> _Ingredients)
{
this.Ingredients = _Ingredients;
this.SumPercentages = _Ingredients.Sum(x => x.Percentage);
}
public Dictionary<Ingredient, decimal> GetWeights(decimal weightTotalDough)
{
return Ingredients.ToDictionary(k => k, v => (v.Percentage / this.SumPercentages) * weightTotalDough);
}
}
By doing it this way, you separate the formula (which is basically just Ingredient/Percentage pairs) from each application of it. You can use the same Formula
object to calculate the weights for 10000g of dough or 50000g of dough - simply call GetWeights()
with a different value.
Notice how many fewer properties you need on each class, and the question of "late setting" of some of them is entirely irrelevant. Effectively, weight is not an intrinsic property of an ingredient, because it varies based on the total weight, so Weight
shouldn't be a property of Ingredient
.