我们有一组大约24个类,它们从一个具有抽象Validate方法的基类继承。当然每个类都有不同的验证需求,但是所有类都需要不同的组合规则,因此,正如您可以想象的那样,这导致了大量代码重复,例如:
A类需要规则1,3,6和9 B类需要规则3,4和8 C类需要规则1,8和9 ....
你明白了。
所以我想做一个简单的重构并创建一个验证装饰器,其中每个规则都封装在一个类和一个工厂中,它将为每个类创建一个adhoc验证组合。
然后我开始认为每个规则都是如此简单,以至于不是为装饰器创建所有管道,而是可能只有Action委托存储在工厂中,这将填充List(Action(T))
以便每个类只会迭代通过该列表执行每个代表。
问题是参数的数量和/或类型在每个规则之间有所不同,例如:
规则1需要可以为空的DateTime,DateTime和枚举 规则2需要可以为空的DateTime和DateTime 规则3需要一个字符串.....
这是可以完成的事情,还是我不能选择编码装饰器?
感谢您的想法和想法。
更新 一些规则示例:
if(EndTime.HasValue && StartTime > EndTime)
Throw new Exception (...);
if(Status == StatusEnum.Pass && !EndTime.HasValue)
Throw new Exception (...);
if(string.IsNullOrEmpty(ProcessName))
Throw new Exception (...);
if(string.IsNullOrEmpty(ProductName))
Throw new Exception (...);
if(string.IsNullOrEmpty(CustomerName))
Throw new Exception (...);
所有涉及的类都包含属性DateTime? EndTime
,DateTime StartTime
,StatusEnum Status
和string ProcessName
。
答案 0 :(得分:1)
首先,您可以创建一个包含所有参数的类,其中布尔值表示哪些是相关的。您也可以创建一个Params委托,但这有点难看(它还要求您将参数转换为对象数组)。
就个人而言,我会选择一个描述所有参数的类。
编辑:
以下是ValiationRuleParameters(包含参数的类)的一个示例:
public class ValidationRulesParam
{
private readonly Dictionary<string, object> _parameters = new Dictionary<string, object>();
public bool AddParam(string name, object value)
{
if (!_parameters.ContainsKey(name))
return false;
_parameters.Add(name, value);
return true;
}
public bool IsTypedParameterSet(string name, Type valueType)
{
object value;
if (_parameters.TryGetValue(name, out value) == false)
return false;
return (value.GetType() == valueType);
}
public TValue GetParamValue<TValue>(string name)
{
object value;
if (_parameters.TryGetValue(name, out value) == false)
return default(TValue);
if (!(value is TValue))
return default(TValue);
return (TValue)value;
}
public object this[string name]
{
get { return GetParamValue<object>(name); }
set { AddParam(name, value); }
}
}
它有点像使用params对象[]和使用普通字典的组合
您可以将此类的实例发送到您运行的每个验证规则(操作),并且阳离子可以测试参数的存在(以及它的类型)。并获得它的价值。
这只是一个例子(并且还有很多需要改进的地方),但它应该能够提供一个表达这个想法的精彩图片。
答案 1 :(得分:0)
为什么不创建一个名为IValidationParameter
之类的接口然后让每个验证规则都有一个IValidationParameter的实现。例如
public class Rule1ValidationParameter : IValidationParameter
{
public DateTime? FirstDate { get; set; }
public DateTime SecondDate { get; set; }
pulbic MyEnum MyEnum { get; set; }
}
然后列出您的列表List<Action<IValidationParameter>>