I have a design problem, and no-one to help me thrash it out. Except for you.
The system handles data files. Each row can be compared against a number of criteria, chosen by the user. The row is then true or false for that criteria.
Each criteria also has a price and a cost (and a margin: price - cost). However, the user is only charged if a row matches one of the criteria. And they only pay for one of the matched criteria: the one used should be the one with the highest margin.
Structurally, it looks like this in pseudo code:
SystemRow
{
bool Criteria1 { get; set; }
bool Criteria2 { get; set; } //etc
}
There's a separate DTO which holds a user's selected criteria as a bitwise Enum. It's passed into a row processing function along with the row.
ProcessRow(selectedCriteria, row)
{
if(selectedCriteria.HasFlag(CriteriaEnum.Criteria1)
{
// this sets row.Critera1 to true if it matches conditions
EvaluateRowForCriteria1(row);
}
// then evaluate other criteria one by one
}
CalculatePrice(ListOfRows)
{
decimal runningTotal;
foreach(row in ListOfRows)
{
runningTotal += [the cost of one - and only one - matching criteria]
}
}
Each of these functions exists in a separate class, in accordance with SRP.
I can think of several ways to do this, but each is messy: hard to maintain and inefficient.
First, I can add a "Price" and "Margin" property to "Row". Then, in the class where "ProcessRow" lives I can pull all the prices and margins from the DB and store them in local variables. During "ProcessRow" I can compare the Margin of a criteria with the Marign of the row and, if better, assign the price. Then I can sum the prices in CalculatePrice.
Second, I can fetch the Price and Margin in CalculatePrice instead. Then, for each row, I can use the selected CriteriaX on the row, find the correct one to charge, and add it to the running total.
What makes this such a mess is that there's about 20 of these criteria. So either way there's going to have to be a ton of variables kicking around if I don't want to have to go to the Db to get the values on each row.
Is there a better design I can leverage here?
criteriaan object withpriceandcostor is it aboolean?