检查输入的最有效方法是什么?
糟糕的例子(我认为):
public int doSthWithAge(int age)
{
if (age > 0)
{
if (age > 100)
{
throw new AgeIsTooHighException();
}
}
else
{
throw new NoWayException();
}
...
}
但有什么好方法?
(如果您要提供任何特定于语言的信息,请执行此操作,就像我使用C#进行验证一样 - -syntax-wise <)>
答案 0 :(得分:4)
一种常见的面向对象验证技术是将验证规则建模为第一类对象:
你会看到很多图书馆都在使用这种技术。
示例:
// the entity you want to validate
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
public class ValidationFailure
{
public ValidationFailure(string description) { Description = description; }
public string Description { get; set; }
// perhaps add other properties here if desired
}
// note that this is generic and can be reused for any object to validate
public interface IValidationRule<TEntity>
{
ValidationFailure Test(TEntity entity);
}
public class ValidatesMaxAge : IValidationRule<Person>
{
public ValidationFailure Test(Person entity)
{
if (entity.Age > 100) return new ValidationFailure("Age is too high.");
}
}
public class ValidatesName : IValidationRule<Person>
{
public ValidationFailure Test(Person entity)
{
if (string.IsNullOrWhiteSpace(entity.Name))
return new ValidationFailure("Name is required.");
}
}
// to perform your validation
var rules = new List<IValidationRule> { new ValidatesMaxAge(), new ValidatesName() };
// test each validation rule and collect a list of failures
var failures = rules.Select(rule => rule.Test(person))
.Where(failure => failure != null);
bool isValid = !failures.Any();
此设计的优点:
if
语句),因为它是一种更面向对象或功能更强的方法,而不是程序性的编辑:@Mgetz提到输入验证与业务验证,这也是一个重要的考虑因素。上面描述的每个规则类的方法基于我每天使用的系统。我们更多地将它用于服务类中的业务逻辑验证(它是一个具有大量业务规则的复杂企业系统),并且该设计很好地满足了我们的目的。我上面写的具体规则非常简单,看起来更像是输入验证。对于输入验证,我建议采用更轻量级的方法,并在适当时将其与业务逻辑验证分开。
这种设计的另一个实现是每个实体都有一个验证器类,并使用更轻量级的东西,例如lambdas用于单独的验证规则。例如,流行的Fluent Validation库使用它。这非常适合用户输入验证,因为它允许更少的代码进行简单的验证,并鼓励您将输入验证与业务逻辑验证分开:
// Example using the FluentValidation library
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(p => p.Age).LessThan(100);
RuleFor(p => p.Name).NotEmpty();
}
}
答案 1 :(得分:3)
验证效率通常不是问题。您应该关注两种类型的验证:
跳过其中任何一种都是一种非常好的方法,最终导致被黑客攻击或严重破坏的应用程序。
如果你正在使用ASP.net,那么有很多库(大多数来自微软)来做前者,Anti-XSS lib等。
后者将在实体本身的共享业务逻辑中最有效地执行。 E.G您的用户实体不应允许年龄为-1。