- 워크플로의 경우
- 입력과 출력을 문서화한 다음 비즈니스 논리에 간단한 의사 코드를 사용합니다.
Bounded context: Order-Taking
Workflow: "Place order"
triggered by:
"Order form received" event (when Quote is not checked)
primary input:
An order form
other input:
Product catalog
output events:
"Order Placed" event
side-effects:
An acknowledgment is sent to the customer,
along with the placed order
- 데이터 구조의 경우
- AND를 사용하여 Name AND Address와 같이 두 부분이 모두 필요함을 의미합니다.
- OR을 사용하여 Email 또는 PhoneNumber와 같이 어느 한 부분이 필수임을 의미합니다.
bounded context: Order-Taking
data Order =
CustomerInfo
AND ShippingAddress
AND BillingAddress
AND list of OrderLines
AND AmountToBill
data OrderLine =
Product
AND Quantity
AND Price
data CustomerInfo = ??? // don't know yet
data BillingAddress = ??? // don't know yet
엔지니어들은 기술적인 문제에 집중하고 모든 요구 사항을 동등하게 취급하는 경향이 있습니다.
기업은 그렇게 생각하지 않습니다. 돈을 버는 것(또는 돈을 절약하는 것)은 거의 항상 개발 프로젝트의 원동력입니다.
도메인 모델의 복잡성을 나타내기
워크플로는 여러개의 단계로 나누어 질 수 있습니다.
또한 종속성(업무적인 - 다른 바운디드 컨텍스트에 의존)이 코드에서의 의존성(ex 의존성 주입 대상)이 된다는 것도 알아둡시다.
이 도표는 우리가 배운 모든 것을 반영하지 않습니다. 텍스트 기반 언어로 이 모든 새로운 정보를 더 잘하고 캡처할 수 있는지 봅시다.
제약 사항 나타내기
제품 코드와 수량은 단순한 문자열과 정수가 아니라 다양한 방식으로 제한됩니다.
context: Order-Taking
data WidgetCode = string starting with "W" then 4 digits
data GizmoCode = string starting with "G" then 3 digits
data ProductCode = WidgetCode OR GizmoCode
설계가 엄격하다고 해서 구현이 엄격해야 하는 것은 아님을 기억하십시오.
예를 들어, 검증 프로세스의 자동화된 버전은 전체 주문을 완전히 거부하는 대신 사람이 승인하도록
이상한 코드에 플래그를 지정할 수 있습니다.
data OrderQuantity = UnitQuantity OR KilogramQuantity
data UnitQuantity = integer between 1 and ?
data KilogramQuantity = decimal between ? and ?
해당 요구사항을 문서화하면서 생각해봅시다. 정말 상한이 없을까요?
이러한 종류의 제약 조건은 포착하는 데 중요합니다.
우리는 생산에서 단위가 음수가 되거나 무게가 수백 킬로톤인 상황을 원하지 않습니다.
다음은 이러한 제약 조건이 문서화된 업데이트된 사양입니다.
data UnitQuantity = integer between 1 and 1000
data KilogramQuantity = decimal between 0.05 and 100.00
데이터(Order)의 생명 주기 나타내기
data Order =
CustomerInfo
AND ShippingAddress
AND BillingAddress
AND list of OrderLines
AND AmountToBill
우리는 도메인 모델에서 이러한 단계를 캡처해야 합니다.
문서화뿐만 아니라 (예를 들어) 가격이 책정되지 않은 주문이 배송 부서로 보내져서는 안 된다는 점을 분명히 하기 위해서입니다.
data UnvalidatedOrder =
UnvalidatedCustomerInfo
AND UnvalidatedShippingAddress
AND UnvalidatedBillingAddress
AND list of UnvalidatedOrderLine
data UnvalidatedOrderLine =
UnvalidatedProductCode
AND UnvalidatedOrderQuantity
data ValidatedOrder =
ValidatedCustomerInfo
AND ValidatedShippingAddress
AND ValidatedBillingAddress
AND list of ValidatedOrderLine
data ValidatedOrderLine =
ValidatedProductCode
AND ValidatedOrderQuantity
- 각 라인에는 연관된 가격이 있습니다. 즉, PricedOrderLine은 ValidatedOrderLine에 LinePrice를 더한 것입니다.
- 전체 주문에는 라인 가격의 합계로 계산된 AmountToBill이 연결되어 있습니다.
data PricedOrder =
ValidatedCustomerInfo
AND ValidatedShippingAddress
AND ValidatedBillingAddress
AND list of PricedOrderLine // different from ValidatedOrderLine
AND AmountToBill // new
data PricedOrderLine =
ValidatedOrderLine
AND LinePrice // new
data PlacedOrderAcknowledgment =
PricedOrder
AND AcknowledgmentLetter
위 디자인에서 다음과 같은 내용을 포착할 수 있습니다.
- 검증되지 않은 주문은 가격 정보가 없습니다.
- validated order 모든 라인이 검증되어야 합니다.
모델이 너무 복잡하다 생각할 수 있으나, 이 정도로 풍부하지 않았다면 요구사항을 포착하지 못했을 것입니다.
첫째, 전체 워크플로의 출력이 이전에 생각했던 것보다 조금 더 복잡합니다. 원래 유일한 출력은 "주문 완료(Order placed)" 이벤트였지만 이제 워크플로의 가능한 결과는 다음과 같습니다.
- “Order placed” event to shipping/billing
- 잘못된 주문 더미(목록함)에 주문 양식을 추가하고 나머지 단계를 건너뜁니다. - 에러처리
workflow "Place Order" =
input: OrderForm
output:
OrderPlaced event (put on a pile to send to other teams)
OR InvalidOrder (put on appropriate pile)
// step 1
do ValidateOrder
If order is invalid then:
add InvalidOrder to pile
stop
// step 2
do PriceOrder
// step 3
do SendAcknowledgmentToCustomer
// step 4
return OrderPlaced event (if no errors)
각각의 서브스텝은 입출력을 갖고 있습니다.
의존성을 따로 확인합니다.
주문 유효성 검사 서브스텝입니다. 오류가 발생할 수 있습니다.
substep "ValidateOrder" =
input: UnvalidatedOrder
output: ValidatedOrder OR ValidationError
dependencies: CheckProductCodeExists, CheckAddressExists
validate the customer name
check that the shipping and billing address exist
for each line:
check product code syntax
check that product code exists in ProductCatalog
if everything is OK, then:
return ValidatedOrder
else:
return ValidationError
주문 가격 계산 서브스텝입니다.
substep "PriceOrder" =
input: ValidatedOrder
output: PricedOrder
dependencies: GetProductPrice
for each line:
get the price for the product
set the price for the line
set the amount to bill ( = sum of the line prices)
substep "SendAcknowledgmentToCustomer" =
input: PricedOrder
output: None
create acknowledgment letter and send it
and the priced order to the customer
> 커맨드 타입 정의 보기
https://itchallenger.tistory.com/421?category=1086398
'BackEnd' 카테고리의 다른 글
도메인 모델을 함수형 아키텍처로 - 컨텍스트 간 통신 2 (0) | 2022.03.17 |
---|---|
도메인 모델을 함수형 아키텍처로 - 컨텍스트 간 통신 1 (0) | 2022.03.17 |
데이터베이스 주도 설계, 클래스 주도 설계 피하기 (0) | 2022.03.17 |
도메인 전문가와 인터뷰. 서브 도메인의 입출력 (0) | 2022.03.17 |
유비쿼터스 랭귀지 만들기 (0) | 2022.03.17 |