進行驗證的一個常見的面嚮對象的技術是您的驗證規則建模爲第一類對象:
- 定義的通用接口,用於驗證特定類型的數據的
- 實現的類或功能的集合符合該接口
- 循環此集合中的每個函數/對象並調用驗證方法。返回值可能是true/false,也可能是描述驗證失敗的對象(如果驗證規則已通過,則返回null)。建立的驗證失敗的列表,同時遍歷規則集合
- 目前驗證失敗的用戶以適當的方式
你會被許多圖書館在那裏看到它使用了這種技術。
實施例:本設計的
// 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();
優點:
編輯:@Mgetz提到輸入驗證VS業務驗證,這也是一個重要的考慮因素。上述的每類規則方法基於我每天工作的系統。我們更多地將它用於服務類中的業務邏輯驗證(這是一個包含大量業務規則的複雜的企業系統),並且設計符合我們的目的。我上面寫的具體規則非常簡單,看起來更像輸入驗證。對於輸入驗證,我建議使用更輕的方法,並在適當時將其與業務邏輯驗證分開。
這個設計的另一個實現是每個實體都有一個驗證器類,並且使用更輕量級的東西,例如lambda表達式來實現單個驗證規則。例如,流行的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();
}
}
您還沒有指定你的語言使用。在PHP中,有一組優秀的[過濾功能](http://php.net/manual/en/book.filter.php),可以爲你做所有這些。在您選擇的平臺中可能有類似的東西。 – 2013-07-05 15:17:49
夠公平的,讓我編輯在C#中做這個問題# –
這個問題問得太寬泛,因爲有很多有效的答案http://stackoverflow.com/help/dont-ask – Mgetz