Sto lavorando su un codice legacy che riguarda gli ordini effettuati dai clienti. C'è un nuovo requisito per classificare ogni ordine per Business Unit. Il nome dell'unità di business verrà archiviato in una nuova colonna nella tabella dell'ordine.
L'ordine non è un oggetto reale. Ho un numero d'ordine, che posso usare per recuperare due diversi documenti XML da un database. Bene , un documento XML che rappresenta l'intero ordine e un documento XML che rappresenta una definizione del prodotto, che viene recuperato utilizzando un ID prodotto dal documento XML dell'ordine. I documenti XML del prodotto sono tutti conformi allo stesso schema.
Ho un set di regole da applicare sui valori ottenuti dai documenti XML per determinare la classificazione della Business Unit.
Sto cercando di evitare di usare molte istruzioni if / else perché sembra disordinato e non molto mantenibile. Tutto ciò di cui ho bisogno è un string
contenente il nome dell'unità di business. Il metodo deve essere chiamato in due flussi separati, quindi l'ho messo in una classe.
Ecco come appare il codice per restituire il nome dell'unità di business:
public class BusinessUnitName
{
public static string GetBusinessUnitName(string orderNumber)
{
var order = getOrder(orderNumber);
var orderType = order.SelectSingleNode("/Order/Type").InnerText;
if (orderType.Equals("Remake"))
{
var remakeReason = order.SelectSingleNode("/Order/RemakeReason").InnerText;
if (remakeReason.Equals("SHIPDMG") || remakeReason.Equals("WRNGITM"))
{
return "Shipping";
}
else
{
return "Customer Service";
}
}
else if (orderType.Equals("Design"))
{
List<string> illustrationProductTypes = new List<string> { "1204", "1205", "1206", "1207" };
List<string> customProductTypes = new List<string> { "9204", "9205", "9206", "9207" };
var firstProductId = order.SelectSingleNode("/Order/Products/Product[1]/Id").InnerText;
var firstProductDefinition = getProductDefinition(firstProductId);
var firstProductType = firstProductDefinition.SelectSingleNode("/Product/Type").InnerText;
if (illustrationProductTypes.Contains(firstProductType))
{
return "Design-Illustration";
}
else if (customProductTypes.Contains(firstProductType))
{
return "Design-Custom";
}
else
{
return "Design-Other";
}
}
else if (orderType.Equals("Samples"))
{
var firstProductId = order.SelectSingleNode("/Order/Products/Product[1]/Id").InnerText;
var firstProductDefinition = getProductDefinition(firstProductId);
var departmentCode = firstProductDefinition.SelectSingleNode("/Product/DepartmentCode").InnerText;
if (departmentCode.Equals("JWL"))
{
return "Jewelry";
}
else if (departmentCode.Equals("SPPLS"))
{
return "Craft Supplies";
}
}
}
private static XmlDocument getOrder(string orderNumber)
{
XmlDocument order = new XmlDocument();
/* execute code to retrieve XML from database
and load into order */
return order;
}
private static XmlDocument getProductDefinition(string productId)
{
XmlDocument productDefinition = new XmlDocument();
/* execute code to retrieve XML from database
and load into productDefinitionXmlDocument */
return productDefinition;
}
}
Questo è abbastanza simile al codice attuale, ma l'elenco di istruzioni if / else è circa tre volte più lungo. Ogni regola consiste semplicemente in una combinazione di valori nei documenti XML.
Non so se sono sulla strada giusta, ma stavo considerando l'utilizzo del modello di strategia. Potrei creare un'interfaccia IBusinessUnitStrategy
con un metodo ExecuteRules
che restituisce un valore bool
che indica se una combinazione di regole è una corrispondenza e un campo che indica il nome dell'unità di business. Dovrei quindi implementare l'IBusinessUnitStrategy per ciascun nome di unità aziendale.
Avrei bisogno di un'altra classe che generi un elenco di istanze di IBusinessUnitStrategy per ogni classe di Business Unit concreta, quindi chiama il metodo ExecuteRules
in sequenza su ogni classe di Business Unit finché uno di questi restituisce true
, quindi restituisce il valore del campo Nome unità di business per quella classe.
Questo approccio avrebbe senso / essere un po 'più lungo in termini di design, o è eccessivo?