Ho implementato un motore di regole come questo:
public interface IRuleEngine
{
List<ValidationMessage> Validate(param1, param2, param3);
}
public class DefaultRuleEngine : IRuleEngine
{
readonly IList<IRule> _rules;
public DefaultRuleEngine()
{
_rules = new List<IRule>()
{
new Rule1(),
new Rule2(),
new Rule3(),
....
};
}
public List<ValidationMessage> Validate(param1, param2, param3)
{
var validationMessageList = new List<ValidationMessage>();
foreach(var rule in _rules)
{
validationMessageList.Add(rule.Validate(param1, param2, param3));
}
return validationMessageList;
}
}
public interface IRule
{
ValidationMessage Validate(param1, param2, param3);
}
public class Rule1 : IRule
{
public ValidationMessage Validate(param1, param2, param3)
{
//do logic, return validation message
return validationMessage;
}
}
Ora, questo funziona bene, ma la manutenzione è stata noiosa. Uso il motore delle regole in molti punti del mio codice. Ho anche dovuto cambiare i parametri necessari in alcune volte, il che ha portato a molte noiose modifiche in tutte le diverse classi in cui lo uso.
Sto iniziando a pensare che questo design non sia eccezionale, e cosa posso fare per cambiarlo. Quello che stavo pensando, invece di passare in ogni singolo parametro, creo una classe ValidationParameters, e la faccio passare. In questo modo, quando ho bisogno di aggiungere un altro parametro - param4 - non devo andare in ogni inserire il codice per apportare la modifica e modificare semplicemente il campo nella classe ValidationParameters. Questo non è un problema, poiché non tutte le regole utilizzano ciascun parametro, quindi non vedo alcun problema. Come, la Regola 1 può usare solo param2 e param3, non param1, per esempio.
public class ValidationParameters
{
public string Param1 {get;set;}
public string Param2 {get;set;}
public int Param3 {get;set;}
public int Param4 {get;set;}
}
e cambia l'interfaccia in
public interface IRuleEngine
{
List<ValidationMessage> Validate(ValidationParameters);
}
questo sembra un buon design, o c'è un modello migliore da usare?