데이터베이스 내용에 의존하는 도메인 모델 규칙의 유효성을 검사 할 수있는 곳은 어디입니까?


10

관리자가 필드를 포함하는 양식을 정의 할 수있는 시스템에서 작업하고 있습니다. 그런 다음 정의 된 양식을 사용하여 시스템에 데이터를 입력합니다. 때때로 폼은 GUI를 통해 사람에 의해 채워지고 때로는 폼은 다른 시스템에 의해보고 된 값에 따라 채워집니다.

각 필드에 대해 관리자는 필드에 허용되는 값을 제한하는 유효성 검사 규칙을 정의 할 수 있습니다. 유효성 검사 규칙은 "필드에 입력 한 값이 True 또는 False 여야 함"에서 "필드에 입력 한 값이 데이터베이스의 테이블 B 열 A에 있어야합니다"까지 될 수 있습니다. 관리자는 언제든지 필드의 유효성 검사 규칙을 변경할 수 있습니다.

이 시나리오에서 각 필드가 올바르게 채워 졌는지 확인하기에 가장 적합한 장소는 무엇입니까? 현재 두 가지 주요 접근 방식이 있습니다.

옵션 # 1 : 도메인 모델에서 확인

각 필드 개체에는 관리자가 지정한 유효성 검사 규칙이 포함됩니다. Field 개체는 IValidator에 대한 참조도 갖습니다. 필드 값을 설정하려고 시도하면 필드는 지정된 값과 유효성 검사 규칙을 IValidator에 전달합니다. 주어진 값이 유효하지 않은 경우, ValidationException이 발생하고 GUI / 인터페이스에서 다른 시스템과 적절히 처리됩니다.

장점 :

  • 유효성 검사 규칙을 위반하는 값이 실수로 할당되는 필드에 대한 강력한 보호

단점 :

  • 데이터 액세스 계층은 유효성 검사를 무시하고 현재 유효성 검사 규칙을 위반하는 필드를 구성 할 수 있어야합니다. 관리자가 필드에 대한 유효성 검사 규칙을 변경하더라도, 예를 들어 몇 년 전에 채워진 양식을 렌더링 할 때 이전 데이터를 기반으로 필드 개체를 구성 할 수 있어야합니다. 필드를 저장할 때마다 현재 유효성 검사 규칙을 저장하면이 문제를 해결할 수 있습니다.

  • 이 설계에서 필드 모델에는 IValidator를 통해 데이터 액세스 계층 / 리포지토리에 대한 간접 링크가 있습니다. 도메인 모델에 서비스 / 리포지토리를 주입하는 것은 일반적으로 싫은 것 같습니다 .

옵션 # 2 : 서비스에서 검증

필드 값을 설정하려는 모든 시도가 유효성 검사 규칙이 유지되도록하는 서비스를 통과하는지 확인하십시오. 유효성 검사 규칙을 위반하면 ValidationException이 발생합니다.

물론 데이터 액세스 계층은 DB에서 이전에 유지되었던 Field 객체를 생성 할 때 서비스를 사용 하지 않습니다 .

장점 :

  • "도메인 모델에 서비스 / 리포지토리를 주입하지 마십시오"라는 생각을 위반하지 않습니다.

  • 필드를 유지할 때 현재 유효성 검사 규칙을 유지할 필요가 없습니다. 서비스는 단순히 해당 필드에 대한 현재 유효성 검사 규칙을 조회 할 수 있습니다. 히스토리 데이터를 볼 때 필드 값은 변경되지 않습니다.

단점 :

  • 필드 값을 설정하기 위해 서비스를 사용해야하는 모든 논리가 실제로 그렇게한다는 보장은 없습니다. 나는 이것을 주요 결점으로 본다. "thisField.setValue (thatField.getValue ())"를 작성하는 사람 만 있으면이 필드의 유효성 검사 규칙을 더 현명하게 위반하지 않을 수 있습니다. 이는 데이터 액세스 계층이 필드를 유지하려고 할 때 필드 값이 유효성 검사 규칙과 일치하도록하여 잠재적으로 완화 될 수 있습니다.

저는 현재 옵션 # 2를 옵션 # 2보다 선호합니다. 주로 이것을 비즈니스 로직으로보고 옵션 # 2가 시스템에 잘못된 데이터를 도입 할 위험이 더 크다고 생각하기 때문입니다. 어느 옵션을 선호합니까, 아니면이 시나리오에 맞는 다른 디자인이 두 옵션보다 더 좋습니까?

편집 (검증의 복잡성)

현재 나온 검증 사례는 비교적 간단합니다. 필드 값은 숫자, 날짜, 시간이 포함 된 날짜이거나 데이터베이스 열의 기존 값이어야합니다. 그러나 시간이 지남에 따라 복잡성이 점차 증가 할 것으로 생각됩니다. 예를 들어, 국제화를 염두에두고 유효성 검증 솔루션을 빌드해야합니다. 날짜와 같은 항목은 로케일 특정 구문으로 입력 될 수 있습니다.

지금은 도메인 모델에 너무 많은 책임을 할당하지 않도록주의하면서 옵션 # 1을 진행하기로 결정했습니다. 비슷한 상황에 처한 사람들은 관련 질문을 확인하고 싶을 수도 있습니다 . 계층 구조의 유효성 검사 및 권한 부여데이터 입력 유효성 검사-어디? 얼마예요? .


모델을 생성하면 모든 유효성 검사에 효과적입니다. 그러나 양식을 편집하거나 보려면 유효성 검사도 시작됩니다. 이로 인해 비어 있거나 유효하지 않은 값이있는 필드 (예 : db에서 변경되거나 Excel에서로드 된 필드)에 예외가 발생합니다. 예상되는 해결책은 관리자가 해당 필드를 수정할 수 있도록 업데이트시 양식을 표시하는 것입니다.
tunmise fasipe

답변:


4

유효성 검사는 얼마나 복잡합니까? 종종 유효성 검사를 수행하려면 필드를 사용하는 필드와 비즈니스 규칙의 조합을 정확하게 평가해야합니다.

검증이 복잡할수록 성능 # 2가 더 어렵고 성능이 떨어집니다.

물론 데이터 계층은 지속 시간에 유효성 검사 서비스를 호출 할 수 있습니다. 이는 규칙 변경으로 인해 데이터가 유효하지 않은 이상한 상황에 도움이 될 수 있습니다.

언급 할 가치가있는 다른 항목은 일종의 qa주기없이 유효성 검사 규칙을 변경할 수있는 기능입니다. 그러나 그것은 다른 스레드에 대한 주제입니다.

위의 정보를 고려할 때, 옵션 1은 검증과 지속성을 분리하여 규율을 유지한다고 가정 할 때 가장 유연 해 보입니다.


0

레이어가 누락되었을 수 있습니다. 응용 프로그램 (필수 사항, 아키텍처 등)의 세부 사항을 알지 못하면 클라이언트와 같은 것을 할 것입니다-> 응용 프로그램 서비스-> 도메인 모델

애플리케이션 서비스 계층은 비즈니스 로직을 포함하는 저장소 및 도메인 모델과 상호 작용할 수 있습니다. 따라서 다음과 같은 것을 가질 수 있습니다.

FieldUpdateService >> updateField(fieldId, newValue)
  List<FieldRule> rules = this.rulesRepository.findRulesFor(fieldId)
  Field field = this.fieldRepository.find(fieldId)
  try 
    field.updateValue(rules,newValue)
    fieldRepository.save(field)
  catch 
    // manage error

Field와 그의 FieldRules 사이에 관계가 있고 Java에서 Hibernate와 같은 ORM을 사용하는 경우 다음을 수행하십시오.

FieldUpdateService >> updateField(fieldId, newValue)
  Field field = this.fieldRepository.find(fieldId)
  try 
    field.updateValue(newValue)
    fieldRepository.save(field)
  catch 
    // manage error

Field >> updateValue(newValue)
  for rule in rules
     if !rule.isValid(newValue)
        throw ValueNotAllowedException
  this.value = newvalue

ORM은 요청한 객체의 그래프를 쿼리하고 인스턴스화하기 때문입니다.

누군가가 할 수 있다는 사실에 대한 당신의 의심에 대하여

thisField.setValue (thatField.getValue ()) "및 thisField의 유효성 검사 규칙이 더 현명하지 않고 위반 될 수 있습니다.

누군가는 다음과 같이 작성할 수도 있습니다. FieldRule alwaysReturnTrueRule = new FieldRule {isValid (newValue) {return true; }} field.updateValue ( "uncheckedValue", alwaysReturnTrueRule) 불분명 한 예이지만, 잘못된 말은 코드의 나쁜 사용으로부터 당신을 보호하는 것은 아무것도 없다는 것입니다. 아마도 좋은 문서와 커뮤니케이션이 대면 할 것입니다. 나는 코드의 나쁜 사용으로부터 당신을 보호하는 것이 아무것도 없다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.