예외가있는 비즈니스 규칙 표현


16

나는 그것이 비싸다는 것을 알고 있지만 (IMO) 나는 그것이 좋은 습관이라고 믿습니다. 나는 영업 사원이 아닌 경우 송장을 저장할 수 없다고 말하는 규칙에 대해 이야기하고 있습니다. 그러면 '귀하의 권한이 없습니다'라는 예외가 발생합니다 ...

다른 접근 방식은 상태 또는 이와 유사한 객체를 갖는 것입니다.

다른 접근법이 있습니까? 너는 어떻게 생각해?

답변:


15

예외와 함께 개별 비즈니스 규칙 검사를 나타내는 것을 의미한다면, 이것이 좋은 생각이라고 생각하지 않습니다. 여러 번 실패 상태를 두 개 이상보고해야하며 첫 번째 상태에서 멈추지 않아야합니다.

반면에, 나는 모든 규칙 을 확인한 다음 요약과 함께 예외 던지는 것이 좋습니다.


1
그것이 바로 내 앱에서 처리하는 방법입니다. FluentValidation을 사용하여 내 인생을 편하게 만들고 ValidateAndThrow 메서드를 사용하면 하루가 절약됩니다.
Matteo Mosca

UI 앱에서는 완전히 동의하지만 서비스 계층 앱에서는 비즈니스 규칙을 준수하지 않는 개체가 전달되면 예외가 발생합니다. 이 두 가지를 함께 사용하는 경우 마지막 문장에서 matiasha가 설명하는 것처럼 때로는 검증 기능이나 복잡한 오류를 추가하는 경우가 있습니다.
Bill

8
던져 도메인 특정의 예외를. 이것은 당신이 사이에 분리 할 수 있습니다 우리하지 않은 우리의 높은 최대.

@ Thorbjørn Ravn Andersen +1 "도메인 특정"위대한 추가
Justin Ohms

1
@JamesPoulson JamesPoulsonException의 하위 클래스로 RuntimeException만든 다음 원래 예외를로 제공하는 것으로 충분할 수 있습니다 cause. 그런 다음 단순히 if (exception instanceof JamesPoulsonException)... 차별화 한다고 말할 수 있습니다 . 이 getCause()방법을 사용하여 원래 예외에 도달하십시오.

9

이 예에서 예외를 제기하는 것은 나쁜 생각이라고 생각합니다. 사용자가 작업을 시작하기 전에 권한이 부여되지 않았지만 여전히 일부 기능을 수행하도록 허용 한 다음 이미 작업을 완료 한 후 메시지와 함께 사용자에게 경고를 표시하는 경우 이는 잘못된 설계입니다.

비즈니스 규칙을 시행하기 위해 예외를 사용하는 것은 좋은 디자인이 아닙니다.


내가 말한 것에 대해 이해하는 것은 UI에 동의하지 않는다는 것입니다. 난 괜찮아 훨씬 더 친숙한 UI를 사용하면 허용되지 않는 것을 업데이트하려고 할 수 없습니다. 그렇다고 비즈니스 코어의 유효성 검사 및 예외 검사가 필요하지 않다는 의미는 아닙니다. 반대로, 나는 그들이 필수라고 믿는다. 잘못 프로그래밍 된 UI가 BL 오용을 허용하지 않도록해야합니다.
Fede

8
@Fede : 우려의 분리 문제입니다. UI는 사용자의 의도를 수집하고 비즈니스 계층에서 피드백을보고 할 책임이 있습니다. 비즈니스 계층의 업무는 UI가 수집 한 정보를 분석하여 정보를 분석하고 UI에 다시보고하거나 데이터 계층에 일부 데이터를 유지하도록 요청하는 것입니다. 이 층들 사이에는 느슨한 결합이 있어야합니다. 느슨한 커플 링에 대한 가난하고 열악한 접근법은 예외입니다. 계층간에 실제 클래스를 공유한다는 의미 일뿐만 아니라 예기치 않은 장애를 처리하기위한 메커니즘을 호출합니다.
Adam Crossland

@ 아담-잘 말하고 정확하게 지적했다.
Walter

1
@Adam-우려되는 문제를 분리하지 마십시오. UI의 어느 누구도 CustomerNameInLowercaseException을 처리 할 것으로 기대하지 않습니다 (예외도 존재하지 않기를 바랍니다). 일반적인 ValidationException 만 처리 할 수 ​​있습니다. 또한 UI는 정보 만 수집하고 모든 정보를 수집해야한다는 점을 100 % 확신합니다. 내가 전에 말한 것은 UI에서 무엇을 하든지 BL은 모든 입력이 정상이라고 가정해서는 안된다는 것입니다. 방어적인 프로그래밍 일뿐입니다.
Fede

@Fede : 모든 입력이 정상인지 확인하는 것이 비즈니스 계층의 작업입니다. UI가 수행하는 경우 비즈니스 로직을 구현하는 것입니다. 이 입력 필드가 숫자로 제한되는 경우가 있고 BL가 보는 지금, 만약 알파 문자 에 의해 모든 수단을 던져 예외 . 구성 요소 가 다른 구성 요소로부터 유효하지 않은 입력 을 수신 할 때마다 예외를 던지는 것은 논리적이고 옳습니다. 인터페이스가 고장 나고 시스템이 고장났습니다. 그러나 입력 유효성 검사는 비즈니스 로직을 실행하는 것과는 매우 다릅니다. 매우 다른 두 가지.
Adam Crossland

5

좋은 비즈니스 로직을 만드는 데 예외를 던지는 가치가 무엇인지 알 수 없습니다. 시스템 작동에 예기치 않은 조건을 해결하기위한 시스템을 사용하지 않는 비즈니스 로직 처리에는 수십 가지 접근 방식이 있습니다.

되는 예상 비즈니스 로직에 조건이 충족되지 않습니다; 이것이 처음에 필요한 이유이며, 예기치 않은 I / O 실패, 메모리 부족 및 널 참조를 처리하는 동일한 메커니즘을 피기 백하고 싶지 않습니다. 이는 시스템 장애이지만 충족되지 않은 비즈니스 조건을 감지하는 것이 시스템의 성공적인 작동입니다.

또한 의도하지 않은 결과에 대해 익히는 시스템입니다. 특정 시점에서 예외를 잡아야하므로 의도하지 않은 어딘가에 새 비즈니스 규칙 예외가 발생하거나 실제로 의도하지 않은 예외를 잡는 비즈니스 규칙을 찾는 코드가있을 수 있습니다. 그것을 위해. 그렇습니다. 이러한 조건은 좋은 코딩 방법으로 설명 할 수 있지만 둘 이상의 개발자가 작업하는 사소한 시스템에서는 실수가 발생하며 값 비싼 실수가 아니기를 바랍니다.


1
예외가 발생하지 않기 때문에 예외를 예외라고합니다. 반면, 서비스 계층에서 예외없이 비즈니스 규칙을 시행하는 것이 반드시 잘못된 것은 아닙니다. 당신은 그것이 사용될 것으로 기대하지 않으며, 클라이언트가 오퍼레이션만을 호출하고 유효한 조건을 만족시키는 데이터 만 제출할 것을 기대합니다. 그러나 클라이언트 코딩에서도 실수가 발생할 수 있으므로 보호 계층을 구축하려고합니다. 데이터베이스에서 외래 키 제약 조건을 사용하는 것과 같은 종류의 사람들은 데이터를 올바르게 삽입하고 업데이트하지만 프로그래밍 오류로 인해 실패 할 수 있다는 것을 알고 있습니다.
Jeremy

2

비즈니스 규칙을 표현하는 것은 한 가지입니다.

사용자 경험에 대해 생각하십시오. 사용자가 영업 사원이 아닌 경우, 왜 그들에게 '송장을 만들'라는 버튼 줄 전혀를 ?


1
버튼을 제공하지 않는다고해서 이것이 어쨌든 무언가를하라는 메시지를 보내지 않는다는 의미는 아닙니다. 그게 전부라면 보안 규칙이 얼마나 쉬운 지 생각해보십시오.
jmoreno

사용자가 X를 할 수 없다면 "Do X"라는 버튼을주지 마십시오. 최고의 보안은 무지입니다. 사용자에게 할 수없는 일에 대해 말하지 마십시오.)
Steven A. Lowe

1

그것은 전적으로 무엇을하고 있는지에 달려 있습니다.

먼저, 실제 행동은 무엇입니까? 누군가 자신의 정보를 입력하는 경우 거부 및 기본적으로 "그렇게 할 수 없습니다"라는 대화 상자가 올바른 것입니다. 양식 입력으로 작업하는 데이터 입력 담당자 인 경우 대화 상자가 적합 할 수 있으며 데이터 입력 담당자는 유효하지 않은 양식을 특수 파일에 넣을 수 있습니다. 일괄 처리를 수행하는 경우 작업을 중단하지 말고 플래그를 지정하고 다음으로 이동하십시오.

동작이 있으면 구현 방법을 결정해야합니다. 예외를 발생시키는 비즈니스 규칙 검사기를 갖는 것이 좋습니다. 리턴 코드를 리턴하고 전달하는 것은 잘못 될 수있는 일이며, 잘못된 항목이 더 이상 발생하는 것을 원하지 않습니다.

성능 비용에 대해 걱정하지 마십시오. 개인이 데이터를 입력하는 경우 관련된 다른 시간에 비해 사소합니다. 일반적으로 인간은 그 시스템에서 가장 많은 시간을 소비합니다. 배치 작업의 경우 예외로 인해 성능 문제가 발생하면 너무 많은 불량 레코드를 입력하게되며 실제로 이러한 모든 처리 및 재 입력은 예외보다 더 큰 문제가됩니다.


0

일관성 있고 강력하고 잘 설계된 예외 API를 갖는 것이 매우 적합합니다. 이것을 사용하여 비즈니스 규칙을 시행하는 것도 적절할 수 있습니다. 실제로 내 경험상 비즈니스 규칙이 복잡할수록 이러한 방식으로 처리 될 가능성이 높아집니다. 권위있는 분기 논리를 작성하는 것보다 예외가 예상되는 시스템을 작성하는 것이 쉽지는 않지만 종종 쉬운 일입니다.

즉, 한 문장으로 설명 할 수있는 간단한 규칙은 일반적으로 규칙에 따라 예방 적 또는 권위적인 방식으로 구현되어야합니다. 그러나 다차원 적이며 3 개 또는 4 개 이상의 요소가 필요한 규칙이있는 경우 (특히 이러한 요소의 선택이 하나 이상의 다른 요소를 기반으로하는 경우) 예외 코딩을 유지 관리하기가 더 쉬울 수 있습니다. 이러한 경우에는 종종 논리 경로에 발생해야하는 많은 전구체 예외 (작업이 수행 될 수없는 이유를 확인)가 수행되고 (또는 그 반대) 보안이 작동하지 않습니다 (작업이 승인되었는지 확인) ), 때로는 확인해야 할 권위있는 누적 논리가있을 수 있습니다 (하위 / 조상 가용성, 객체를 넣어야하는 전구체 상태 등).

이러한 유형의 예외 처리에서 파생되는 이점 중 하나는 프로젝트의 여러 영역에서 전조 예외를 분리하여 재사용 할 수 있다는 것입니다. (이것은 Aspect 지향 프로그래밍의 본질입니다.)이를 통해 일반 비즈니스 규칙의 특정 측면을 독립적이고 유지 관리 가능한 구성 요소로 캡슐화합니다. 일반적으로 이러한 구성 요소는 1-1에 해당하는 오류 메시지와 일치합니다. (때로는 여러 다른 예외를 발생시키는 하나의 구성 요소가 있지만 여러 구성 요소에서 동일한 예외가 발생하지 않아야합니다.)

제 생각에는 예외 기반 시스템을 설계하는 것이 더 어렵고 모든 N 레벨에서 예외 프로세스를 빌드해야하기 때문에 초기 개발 시간이 더 깁니다. 그러나 이러한 시스템은 일반적으로 훨씬 더 안정적입니다. '실패하지 않을'시스템을 설계하는 것은 불가능하지만 예외 기반 설계의 이점은 항상 장애를 예상한다는 것입니다. 대부분의 사람들에게이 과정은 반 직관적 일 수 있습니다. 길 찾기를 요청하고 다른 사람에게 모든 거리를 알려주지 말아야합니다.

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