我正在编写验证引擎。
我给出了一个包含大约40个不同属性列表的对象有效负载。每个房产都将进行不同的验证。
验证包括检查字段是否为字符串并验证长度是否超过db设置的允许限制,并且还有条件检查空值和空字段。
所以,我想到了选择策略模式。
代码:
interface IValidationEngine
{
Error Validate(string propName, dynamic propValue);
}
public class StringLengthValidator : IValidationEngine
{
static Dictionary<string, int> sLengths = new Dictionary<string, int>();
public StringLengthValidator()
{
if (sLengths.Count == 0)
{
sLengths = new Dictionary<string, int>(){....};
}
}
public Error Validate(string name, dynamic value)
{
var err = default(Error);
//logic here
return err;
}
}
public class MandatoryValidator : IValidationEngine
{
public Error Validate(string name, dynamic value)
{
var err = default(Error);
//logic here
return err;
}
}
public class MandatoryStringLengthValidator : IValidationEngine
{
public Error Validate(string name, dynamic value)
{
var e = default(Error);
if (value == null || (value.GetType() == typeof(string) && string.IsNullOrWhiteSpace(value)))
{
e = new Error()
{
//.. err info
};
}
else
{
StringLengthValidator sl = new StringLengthValidator();
e = sl.Validate(name, value);
}
return e;
}
}
还有另一个我把它命名为ValidationRouter
的类。这项工作的目的是路由到特定的验证器(将此视为Strategy as per pattern)。
我写了一个初始路由器,它有一个密钥字典及其各自的对象映射,这样任何进来的东西都会匹配它的密钥,并在字典值上调用适当的validate()
方法。但是在创建新对象时添加键和值。我认为这个类会占用很多内存,因为我在构造函数中创建了对象。
所以,我已经将Lazy添加到对象创建中,它最终就像这样
这是路由器的代码
public class ValidationRouter
{
public Dictionary<string, Lazy<IValidationEngine>> strategies = new Dictionary<string, Lazy<IValidationEngine>>();
public ValidationRouter()
{
var mandatoryStringLength = new Lazy<IValidationEngine>(() => new MandatoryStringLengthValidator());
var mandatory = new Lazy<IValidationEngine>(() => new MandatoryValidator());
var stringLength = new Lazy<IValidationEngine>(() => new StringLengthValidator());
strategies.Add("position", mandatoryStringLength);
strategies.Add("pcode", stringLength);
strategies.Add("username", mandatoryStringLength);
strategies.Add("description", stringLength);
strategies.Add("sourcename", stringLength);
//OMG: 35 more fields to be added to route to specific routers
}
public Error Execute(string name, dynamic value)
{
//Find appropriate field and route to its strategy
var lowered = name.ToLower();
if (!strategies.ContainsKey(lowered)) return default(Error);
return strategies[lowered].Value.Validate(name, value);
}
}
正如您所看到的,我需要在构造函数中使用适当的策略向字典添加35个以上的键。
方法是否正确或是否有更好的路由到特定验证器算法的方法?
我认为对象创建是由Activator.CreateInstance
的工厂模式完成的,但不确定如何实现,因为我的每个属性都有不同的策略。
任何想法都会受到赞赏。