2012-03-05 2 views
0

우리 시스템에는 다양한 사용자 정의 특성을 가질 수있는 엔티티 Product이 있습니다. 속성 집합은 제품마다 다를 수 있으며 List<Property> 필드에 저장됩니다. 속성은 다른 유형 (문자열, int, double)이며 몇 가지 특수한 특성을 가질 수 있습니다. 그들은 여러 값을 가질 수도 있고, 특정 범위의 값이거나, 주어진리스트의 값일 수도 있습니다. 속성의 값은 항상 문자열 필드 Value에 포함됩니다.유효성 검사 오류 계층 설계

현재 나의 현재 문제는 이러한 속성의 유효성 검사를 구현하는 것이고 유효성 검사 결과의 erpresentation의 일부로 어떤 접근법을 취해야하는지에 대해 고민하고 있습니다. 만족해야하는 요구 사항 : - 유효성 검사 결과가 다른 응용 프로그램 계층에서 사용되므로 결과 API는 명확하고 사용하기 쉬워야합니다. - 각 오류마다 고유 한 표현이 있어야합니다. - API 사용자는

  1. 클래스 : 정보

    여기

    내가 지금까지 생각했던 방법은 (범위 오류에 대한 예를 들어 그들은 최소한의 가능한 값, 최대 가능 값과 실제 값으로 제공되어야한다) 오류 세부 사항을 이해하기 계층. 하나의 기본 추상 클래스 ValidationError이 있으며 각각의 특정 오류는 상속 된 클래스에 반영됩니다. 오류가 구체화되면, 해당 클래스는 모든 정보를 저장하는 데 필요한 필드를 갖게됩니다. 예 :

    public abstract class ValidationError 
    { 
        // common fields and methods, if any 
    } 
    
    public class IncorrectFormatValidationError : ValidationError 
    { 
        // just empty class, nothing to add here 
    } 
    
    public class RangeValidationError : ValidationError 
    { 
        public object MinValue { get; set; } 
    
        public object MaxValue { get; set; } 
    } 
    

    이 방법은 실제로는 다양한 빈 클래스로 인해 다소 과장된 것으로 보입니다. 그런 API의 사용법은 맞지 않습니다 (if (typeof(error) == typeof(RangeValidationError)) - 난센스!). 그러나 이것은 내 마음에 온 첫 번째 것입니다.

  2. 오류 열거 형 및 필요한 경우 클래스 계층 구조. 모든 오류는 열거 형으로 표시됩니다. 대부분의 경우에 사용되는 하나의 클래스 ValidationError이 있으며 특정 오류에 대한 추가 정보가 필요한 경우 기본적으로 첫 번째 방법과 동일한 방식으로 상속자가 만들어집니다. 예 :

    public enum ValidationErrors 
    { 
        IncorrectFormat, 
        ValueNotWithinRange, 
        ... 
    } 
    
    public class ValidationError 
    { 
        public ValidationErrors ErrorType { get; set; } 
    
        public ValidationError(ValidationErrors type) 
        { 
         this.ErrorType = type; 
         ... 
        } 
    
        // common fields and methods, if any 
    } 
    
    public class RangeValidationError : ValidationError 
    { 
        public object MinValue { get; set; } 
    
        public object MaxValue { get; set; } 
    
        public RangeValidationError(object minValue, object maxValue) : 
         base(ValidationErrors.ValueNotWithinRange) 
        { 
         ... 
        } 
    } 
    

    이러한 접근 방식은 훨씬 좋아 보이지만 단점도 있습니다. 가장 큰 것 중 하나는 API 사용자로서 우리가 ValueNotWithinRange 유형의 오류가있을 때 RangeValidationError 유형의 클래스를 처리한다는 것을 보장 할 수 없다는 것입니다. 그렇지 않은 경우 어떻게 처리합니까? API를 개발하는 사람이 아니기 때문에 이러한 상황이 발생하지 않도록하는 디자인 수준의 기능을 갖고 싶습니다. 이 접근 방식의 또 다른 문제는 대부분의 오류는 결국 몇 가지 추가 정보를 필요로하는 경우, 우리는 결국 1

누구든지이 두 가지 접근 방법 또는에서 공유 어떤 생각을 가지고 같은 aprroach 번호로 끝날 것이 오 더 나은 것을 제안합니까? 나는 모든 응답을 매우 높이 평가할 것이다. 미리 감사드립니다. 거의 당신이 이미 검증의 계층 구조를 보장 있기 때문에

답변

0

다시 단계를 가지고 접근 "검증을 오류를 나타내는 여러 클래스"전체를 다시 생각하는 것이 좋습니다 수 있습니다.

모든 유효성 검사 오류가 완벽하게 주어진 지정된 수 : 을 검증 실패 속성

  • 재산
  • 값의 이름 값을 승인하지 못하여

    1. 유효성 검사기

      추가 정보 (예 : 범위의 한계, 일치하지 않는 정규 표현식)는 이미 유효성 검사기 인스턴스에 있으며이를 통해 액세스 할 수 있습니다.

      그래서 다음과 같습니다 하나의 유효성 검사 오류 클래스를하는 것에 대한 어떤 :

      public sealed class ValidationError 
      { 
          public Validator Validator { get; set; } 
          public string PropertyName { get; set; } 
          public object AttemptedValue { get; set; } 
      } 
      
  • +0

    실제로 이런 식으로 계층 복제를 피할 수 있지만 추상 Validator에 대한 추가 다운 캐스팅도 소개합니다. Validator를 형식 매개 변수로 변경하는 방법을 제안합니다. – Basilevs

    +0

    @Basilevs : 계층 루트 (예 :'Min' 및'Max' 속성)에없는 멤버에 액세스해야하는 경우 다운 캐스팅이 필요합니다 ('ValidationError' 계층에서도). 유일한 다른 방법은 런타임에 속성 값에 동적으로 액세스 할 수있는 기능을 구축하는 것입니다.이 기능은 리플렉션 사용과 도덕적으로 동일하며 기본 유형과 동일한 기본 문제가 있습니다. – Jon

    +0

    @ 존, 응답 해 주셔서 감사합니다. 아니, 지금까지 유효성 검사기가 없습니다. 모든 유효성 검사는 여러 BL 수준 방법으로 수행됩니다. 어쩌면 그들의 소개에 대해 생각할 가치가 있을까요? 그러나 그렇다면 우리는 오류 (질문에 설명 된)와 동일한 문제에 직면 해 있습니다. 그렇지 않습니까? – Andrei

    0

    당신은 FluentValidation 같은 것을 살펴 할 수 있습니다. 가볍고 직관적이며 많은 검증 시나리오를 포함합니다.

    FluentValidation에서 사용하는 유효성 검사 결과가 만족스럽지 않은 경우 사용자 지정 유효성 검사 오류 클래스로 항상 래핑 할 수 있습니다. 적어도 무료로 많은 기본 기능을 사용할 수 있습니다.