도메인 대 데이터 지속성 계층의 클린 아키텍처 검증?


13

저는 깨끗하게 공부하고 있으며 결과적으로 소프트웨어를 디자인하고 작성하는 방법을 상당히 많이 재고하고 있습니다.

그래도 여전히 씨름하고있는 것은 "일부 항목에 대한 업데이트 저장시 먼저로드 /보기 / 수정 권한이있는 모든 항목 목록 등의 비즈니스 규칙에 대한 것입니다.이 항목이 목록에 있는지 확인하십시오. 항목 카테고리가 현재 사용 (및 기타 규칙 등)에서 잠기지 않았습니다. ".. 왜냐하면 (복잡하지만 비정형적인) 비즈니스 규칙이기 때문에 비즈니스 로직을 적용하기보다는 애플리케이션 도메인에서 처리해야합니다. db / persistence 레이어

그러나 이러한 조건을 효율적으로 확인하려면 모든 데이터를 응용 프로그램 도메인에로드하는 대신 잘 만들어진 db 쿼리로 처리하는 것이 가장 좋습니다 ...

조기에 최적화하지 않으면이 질문을 다루는 권장되는 접근 방식이나 Bob의 아저씨 기사가 무엇입니까? 또는 "문제가 될 때까지 도메인에서 확인"이라고 말합니까?

가장 기본적인 사용 사례 이외의 다른 좋은 예제 / 샘플을 찾기 위해 고심하고 있습니다.

최신 정보:

안녕하세요, 답장을 보내 주셔서 감사합니다. 나는 더 명확해야했고, 오랫동안 (대부분 웹 응용 프로그램) 소프트웨어를 작성해 왔으며, 이미 포괄적으로 설명하는 모든 주제에 대해 이미 경험하고 동의했습니다 (백엔드로 확인, 클라이언트 데이터를 신뢰하지 않음, 일반적으로 말하기 필요할 때만 원시 효율성을 추구하지만, 사용 가능한 경우 db 툴의 장점을 인정하는 등) "모두 함께 던져"라는 개발자 학습 라이프 사이클을 거쳐 "N- 계층 애플리케이션으로 거대한 지방 컨트롤러 구축"코드 추세 , 그리고 최근에는 프로젝트가 발전하고 고객의 요구 사항이 더욱 밝아짐에 따라 최근에 상당히 어수선하고 널리 분산 된 비즈니스 규칙으로 발전한 몇 가지 프로젝트의 결과로 청정 / 단독 책임 스타일 등을 실제로 좋아하고 조사하고 있습니다.

특히, 클라이언트와 내부 사용 기능을위한 REST API를 구축하는 맥락에서 Clean 스타일 아키텍처를 살펴보고 있습니다. 여기서 많은 비즈니스 규칙은 기본적으로 인터넷에서 보는 모든 예제보다 훨씬 더 복잡 할 수 있습니다. (Clean / Hex 아키텍처 사용자들조차도).

따라서 Clean과 REST API가 함께 앉아있는 방법에 대해 실제로 묻고 있었으며 명확하게 설명하지 못했습니다. 요즘 대부분의 MVC 항목에는 들어오는 요청 유효성 검사기 (예 : .NET의 FluentValidation 라이브러리)가 있지만 내 "유효성 검사"규칙은 "이것은 50 자 미만의 문자열입니까?"가 아니라 "이 사용자 사례 / 인터랙 터를 호출하는이 사용자가 일부 관련 오브젝트가 현재 팀 X에 의해 잠겨있는 경우이 데이터 콜렉션에서이 조작을 수행 할 수 있습니까?" 비즈니스 도메인 객체의 LOTS 및 도메인 규칙이 적용되는 종류의 깊이있는 검증.

FluentValidator 프로젝트에서 영감을 얻었지만 더 많은 비즈니스 로직과 데이터 액세스가 포함 된 각 유스 케이스 인터랙 터와 함께 특정 규칙의 Validator-object 유형으로 규칙을 분리해야하는 경우 게이트웨이와 같은 유효성 검사를 처리해야합니까? 그 유효성 검사를 게이트웨이에 넣으십시오 (잘못 생각합니다) 등

참고로, 내가 좋아하는 몇 가지 기사 떨어져 가고 있지만, 마티아는 많은 검증을 설명하지 않습니다.

그러나 내 질문에 대한 짧은 대답은 내가 받아 들인 대답과 매우 비슷하다고 생각합니다.


2
"정확한"것과 "실용적인"사이에는 종종 차이가 있습니다. 선택이 주어지면 어느 것을 선호합니까?
Robert Harvey

"모든 항목 목록로드"는 비즈니스 규칙처럼 보이지 않으며 구현 세부 정보로 너무 많이 들어가는 것 같습니다. 로드하지 않고 db 쿼리를 사용하여 규칙을 충족 할 수있는 경우 규칙에 "로드"라고 표시되는 이유는 무엇입니까?
Monica

답변:


31

데이터 입력의 유효성 검사는 모든 사람들이 순수하고 깨끗하게 만들려고 노력하기 시작하고 (그들이 현명하다면) 결국에는 포기하는 것 중 하나입니다. 경쟁에 대한 우려가 너무 많기 때문입니다.

  • UI 계층은 사용자에게 실시간 피드백을 제공하기 위해 클라이언트 페이지 / 양식에서 바로 어떤 형태의 유효성 검사를 수행해야합니다. 그렇지 않으면 사용자는 트랜잭션이 네트워크를 통해 게시되는 동안 피드백을 기다리는 데 많은 시간을 소비합니다.

  • 클라이언트는 신뢰할 수없는 컴퓨터 (예 : 거의 모든 웹 응용 프로그램)에서 실행되기 때문에 코드를 신뢰할 수있는 서버 측에서 이러한 유효성 검사 루틴을 다시 실행해야합니다.

  • 입력 제약으로 인해 일부 형태의 유효성 검사가 암시 적입니다. 예를 들어, 텍스트 상자는 숫자 입력 만 허용 할 수 있습니다. 이것은 "숫자입니까?"가 없을 수도 있음을 의미합니다. UI 제약 조건을 우회 할 수 있기 때문에 (예 : Javascript를 비활성화하여) 페이지의 유효성 검사기를 백엔드에 여전히 필요합니다.

  • UI 공격은 시스템을 주입 공격이나 기타 악의적 인 데이터 입력 형식으로부터 격리시키기 위해 서비스 경계에서 몇 가지 형태의 유효성 검사 (예 : 웹 응용 프로그램의 서버 측 코드)를 수행해야합니다. ASP.NET 요청 유효성 검사 와 같은 코드 기반에도이 유효성 검사가 포함되지 않는 경우가 있습니다 .

  • UI 계층은 사용자가 입력 한 데이터를 비즈니스 계층이 이해할 수있는 형식으로 변환하기 위해 일부 형태의 유효성 검사를 수행해야합니다. 예를 들어 문자열 "6/26/2017"을 적절한 시간대의 DateTime 개체로 바꿔야합니다.

  • 비즈니스 계층은 이론적으로 비즈니스 계층에 속하기 때문에 대부분의 유효성 검사 형식을 수행해야합니다.

  • 특히 참조 무결성 검사가 필요한 경우 (예 : 상태 코드가 50 개의 유효한 상태 목록에 있는지 확인하기 위해) 일부 형태의 유효성 검사가 데이터베이스 계층에서보다 효율적입니다.

  • 동시성 문제로 인해 데이터베이스 트랜잭션의 컨텍스트에서 일부 형태의 유효성 검사가 발생해야합니다. 예를 들어, 고유 한 사용자 이름을 예약하는 것은 원자 적이어야하므로 처리 중에 다른 사용자가이를 파악하지 못합니다.

  • 일부 형태의 검증은 우편 번호와 도시 이름이 함께 있는지 확인하는 경우와 같이 타사 서비스를 통해서만 수행 할 수 있습니다.

  • 시스템 전반에 걸쳐, 코드 결함이있는 경우 합리적인 실패 모드를 보장하기 위해 널 (null) 점검 및 데이터 변환 점검이 여러 계층에서 발생할 수 있습니다.

일부 개발자는 비즈니스 계층의 모든 유효성 검사 규칙을 체계화 한 다음 다른 계층에서 비즈니스 규칙을 추출하고 다른 계층에서 유효성 검사를 재구성하도록 요청합니다. 이론적으로 이것은 당신이 하나의 진실한 근원으로 끝나기 때문에 좋을 것입니다. 그러나 나는이 접근법이 불필요하게 솔루션을 복잡하게 만드는 것 이외의 다른 일을하는 것을 본 적이 없으며, 종종 매우 나쁘게 끝납니다.

따라서 유효성 검사 코드가 어디로 가는지 알아 내려고 노력하고 있다면 약간 복잡한 문제에 대한 실질적인 해결책으로 유효성 검사 코드가 여러 곳에서 끝날 것입니다.


UI가 모든 사용자의 피드백을 관리한다고 생각하는 경우 데이터베이스에서 대부분의 유효성 검사를 푸시하고 비즈니스 계층에서 수행 할 수없는 작업 만 유지할 수 있습니다. 매우 자세한 메시지 문제 해결로 전체 백엔드 API를 설계하면 문제가 발생합니다.
Walfrat

2

유효성 검사는 비즈니스 계층의 일부입니다.

요점은 : DAO의 비즈니스 로직이 DAO의 개념을 무효화 할 것이라는 점입니다. 상위 계층에서 유효성 검사를 수행하면 다른 사용 사례에서 비즈니스 작업을 호출 할 경우 중복 유효성 검사가 수행됩니다.

UI의 보안을 평가할 수 있습니다. 그러나 보안 도메인 개체가 중요한 작업을 수행하므로 선택 사항입니다. UI에서 현재 로그인 한 사용자가 가지고있는 권한에 따라 컴포넌트를 보이거나 보이지 않게합니다. 그러나 이것은 사용자 경험의 일부일뿐입니다. 허용되지 않은 작업을 수행하려고 할 때마다 사용자가 보안 예외에 빠지지 않도록하십시오.


2

누가 유효성 검사를 수행하고 있는지에 대한 관점을 확인하고 싶을 수도 있습니다. DB로 작업하고 있음을 알고있는 DB입니까? 또는 서비스 (DB 작업으로 백업 및 제어되는 서비스)입니까? 내 프로젝트에는 모든 집계 루트에 읽을 수있는 그룹 목록과 수정 자 목록이 있습니다. 코드가 사용자가 볼 수있는 특정 루트 또는 루트 목록을 찾으면 모든 세부 정보가 사용자 ID와 타일이 "blah"로 시작하는 위치와 같은 조회 컨텍스트의 추가 부분을 취하는 서비스 뒤에 숨겨집니다. 이 코드는 DB가 존재 그룹을 수행하는 것을 신경 쓰지 않으며 사용자 그룹이 독자 그룹에 있는지 확인합니다. 그것은 단지 계약에 의해서만 정의 된 서비스가 제공하는 것에 기초하여 내용이 있거나없는 목록을 기대할뿐입니다.

레이어 아래에 모두 적용됩니다. 유효성 검사의 균일 성이 핵심입니다. 도메인에서 가능한 많은 검증을 수행하십시오. API로 제약 조건을 반환하십시오. 나는 X 라이브러리 또는 Z 스토리지에서 오는 것이 아니라 서비스에서 오는 제약을 생각하지 않습니다.


0

일부 유효성 검사 논리가 데이터베이스 쿼리 형식으로 가장 단순하고 명확하게 표현되면 답을 얻을 수 있습니다. 그러나 알려진 성능 문제가있는 경우에만 효율성 이 문제가되며 그렇지 않은 경우 조기 최적화입니다.

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