Ho un problema di progettazione e nessuno che mi aiuti a sfidarlo. Tranne te.
Il sistema gestisce i file di dati. Ogni riga può essere confrontata con un numero di criteri, scelti dall'utente. La riga è quindi vera o falsa per quel criterio.
Ogni criterio ha anche un prezzo e un costo (e un margine: prezzo - costo). Tuttavia, l'utente viene addebitato solo se una riga corrisponde a uno dei criteri. E pagano solo per uno dei criteri corrispondenti: quello usato dovrebbe essere quello con il margine più alto.
Strutturalmente, appare come questo in pseudo codice:
SystemRow
{
bool Criteria1 { get; set; }
bool Criteria2 { get; set; } //etc
}
Esiste un DTO separato che contiene i criteri selezionati dall'utente come Enum bit a bit. È passato in una funzione di elaborazione di riga insieme alla riga.
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]
}
}
Ciascuna di queste funzioni esiste in una classe separata, in conformità con SRP.
Posso pensare a diversi modi per farlo, ma ognuno è disordinato: difficile da mantenere e inefficiente.
In primo luogo, posso aggiungere una proprietà "Prezzo" e "Margine" a "Riga". Quindi, nella classe in cui vive "ProcessRow", posso prelevare tutti i prezzi e i margini dal DB e memorizzarli in variabili locali. Durante "ProcessRow" posso confrontare il Margine di un criterio con il Marign della riga e, se possibile, assegnare il prezzo. Quindi posso sommare i prezzi in CalculatePrice.
In secondo luogo, posso recuperare il prezzo e il margine in CalculatePrice. Quindi, per ogni riga, posso utilizzare il criterio selezionato X sulla riga, trovare quello corretto da addebitare e aggiungerlo al totale parziale.
Ciò che rende questo pasticcio è che ci sono circa 20 di questi criteri. Quindi, in ogni caso, ci sarà un sacco di variabili a dare il calcio d'inizio se non voglio andare al Db per ottenere i valori su ogni riga.
C'è un design migliore che posso sfruttare qui?