반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 쿠버네티스
- 루씬 인 액션
- @configuration
- 알고리즘
- 커링
- 기능개발
- Java
- 스택/큐
- K번째수
- 완주하지 못한 선수
- @EnableScheduling
- 프로그래머스
- 전화번호 목록
- 검색 기능 확장
- 정렬
- H-index
- @Data
- 스프링 스케쥴러
- 다리를 지나는 트럭
- @Setter
- 크론 표현식
- 고차원 함수
- @Getter
- 가장 큰 수
- 모던 자바 인 액션
- 코딩 테스트
- 영속 자료구조
- kubenetes
- 해시
- 롬복 어노테이션
Archives
- Today
- Total
Today I Learned
[도메인 주도 설계] 09. 암시적인 개념을 명확하게 (1) 본문
728x90
도메인의 본질적인 개념을 모댈 내에 표현하고, 지식탐구와 리팩토링을 반복하면서 심층적인 모델로 정제하게 된다.
언어에 귀 기울여라
- 도메인 전문가가 사용하는 언어에 모델의 개념에 기여하는 실마리가 있다.
- 팀에서 사용하는 언어와 전문가의 견해, 도메인과 관련된 문서를 통해 암시적인 개념을 드러내는 단서를 찾아야 한다.
- 사용자나 도메인 전문가가 설계상의 어디에도 표현되어 있지 않은 어휘를 사용하고 있다면 주의해야한다.
- 예제 : 해운 모델의 누락된 개념에 귀 기울이기
- 기존의 예약 애플리케이션에서는 화물에 대한 운송 계획을 수립할 때 Rounting engine을 사용해서 각 운항 구간(leg)을 데이터베이스 테이블의 한 레코드로 저장한다.
- 그런데 도메인 전문가와 대화를 통해 화물에 대한 운항일정(Itinerary)가 중요하다는 것을 알게 되었다.
- 이렇게하면 라우팅 엔진이 데이터베이스 테이블 스키마를 알 피요가 없다는 장점도 있었다.
- 그래서 데이터를 테이블에 저장하는 대신 Routing Service가 Itinerary 객체를 반환하도록 만들었다.
- 명시적인 Itinerary 객체로 리팩터링한 결과로 얻게된 이점은 다음과 같다.
- Routing Service의 인터페이스를 좀 더 표현력 있게 정의
- Routing Service에서 예약 데이터베이스 테이블로의 결합 제거
- 예약 애플리케이션과 운영 지원 애플리케이션 간의 (Itinerary 객체를 공유하는) 관계를 명확하게 표현
- Itinerary로부터 예약 보고서와 운영지원 애플리케이션 모두에 대한 적재/하역 시간 도출이 가능해져서 중복코드 줄어듦
- 예약 보고서로부터 도메인 로직을 제거하고 별도의 도메인 계층으로 옮김
- UBIQUITOUS LANGUAGE를 확장함으로써 개발자와 도메인 전문가, 그리고 개발자 간의 모델과 설계에 대한 정확한 논의가 가능해짐
- 기존의 예약 애플리케이션에서는 화물에 대한 운송 계획을 수립할 때 Rounting engine을 사용해서 각 운항 구간(leg)을 데이터베이스 테이블의 한 레코드로 저장한다.
어색한 부분을 조사하라
- 필요한 개념이 늘 대화나 문서로 인식할 수 있을 만틈 확연히 드러나지는 않는다.
- 설계에서 어색한 부분을 조사하고 도메인 전문가와 함꼐 누락된 개념을 발견해야 한다.
- 예제 : 이자 수익 예제 - 어려운 방식으로 접근하기
- 다음은 기업대출과 그 밖의 이자부 자산에 투자하는 금융회사의 애플리케이션이다.
- 매일 밤 실행되는 배치 스크립트는 해당 일자의 이자를 계산하기 위해 모든 Assert(자산)의 CalculateInterestForDate() 메서드를 호출한다.
- 메서드의 반환값(수익금)과 특정 원장(ledger)의 이름은 회계 프로그램에 대한 공용 인터페이스를 제공하는 SERVICE로 전달한다.
- 회계 소프트웨어는 지정된 원장에 수익금을 기입한다. Assert에 대한 일별 수수료 계산도 유사한 방식으로 처리된다.
- 하지만 점점 복잡해지는 이자 계산 방식으로 리팩토링이 필요해보였다. 전문가와의 대화를 통해 이자수익(interest earned)와 상환(payment)이 별개의 기입 항목이며, 원장도 각각 기입한다는 것을 알게되었다.
- 이를 바탕으로 리팩터링된 애플리케이션에서 야간 배치 스크립트는 각 Assert(자산)의 calculateAccrualsThroughDate() 메서드를 실행한다.
- 이 메서드는 Accural(발생)의 컬렉션을 반환하며, 각 Accural의 금액은 명시된 원장에 기입된다.
- 새로운 모델은 다음과 같은 장점이 있다.
- "발생"이라는 용어를 추가해서 UBIQUITOUS LANGUAGE가 풍부해졌다.
- 상환에서 발생을 분리했다.
- 도메인 지식(이를테면, 어느 원장에 기입할 것인지와 같은)을 스크립트에서 도메인 계층으로 옮겼다.
- 업무에 적합하게 수수료와 이자를 하나의 개념으로 묶어 코드상의 중복을 제거했다.
- 새로운 수수료와 이자 처리 방식을 간단하게 추가하기 위한 Accural Schedule(발생 기록)
- 다음은 기업대출과 그 밖의 이자부 자산에 투자하는 금융회사의 애플리케이션이다.
다소 불명확한 개념을 모델링하는 법
- "명사와 동사"로 표현되지 않는 다른 중요한 범주의 개념도 모델 내에 명시적으로 표현할 수 있다.
- 명시적인 제약조건
- "Bucket" 객체는 제한된 용량을 초과해서 저장할 수 없다는 불변식을 만족시켜야 한다.
- 불변식이 간단한 경우에는 다음처럼 contents를 변경하는 개별 연산 안에 조건 로직을 사용해서 불변식을 보장할 수 있다.
class Bucket { private float capacity; private float contents; public void pourIn(float addedVolume) { if (contents + addedVolume > capacity) { contents = capacity; } else { contents = contents + addedVolume; } } }
- 하지만 제약조건을 파악하기 어려운 복잡한 클래스라면 제약조건을 따로 분리할 수 있다.
class Bucket { private float capacity; private float contents; public void pourIn(float addedVolume) { float volumePresent = contents + addedVolume; contents = constrainedToCapacity(volumePresent); } private float constrainedToCapacity(float volumePlacedIn) { if (volumePlacedIn > capacity) return capacity; return volumePlaceIn; } }
- "Bucket" 객체는 제한된 용량을 초과해서 저장할 수 없다는 불변식을 만족시켜야 한다.
- 어떤 제약조건을 포함한 객체의 설계가 잘못되어있다는 조짐
- 제약조건을 평가하려면 해당 객체의 정의에 적합하지 않은 데이터가 필요하다.
- 관련된 규칙이 여러 객체에 걸쳐 나타나며, 동일한 계층구조에 속하지 않는 객체 간에 중복 또는 상속 관계를 강요한다.
- 설계와 요구사항에 관한 다양한 논의는 제약조건에 초점을 맞춰 이뤄지지만 정작 구현 단계에서는 절차적인 코드에 묻혀 명시적으로 표현되지 않는다.
- 제약조건이 객체가 담당하는 기본 책임을 모호하게 만들거나 모델 내에 명확하게 표현되어 있지 않다면 제약조건을 명시적인 객체로 분리하거나, 나아가 일련의 객체와 관계의 집합으로 모델링할 수 있다.
728x90
'도메인 주도 설계' 카테고리의 다른 글
[도메인 주도 설계] 10. 유연한 설계 (1) (0) | 2022.02.11 |
---|---|
[도메인 주도 설계] 09. 암시적인 개념을 명확하게 (2) (0) | 2022.01.26 |
[도메인 주도 설계] 08. 도약 (0) | 2022.01.11 |
[도메인 주도 설계] 3부. 더 심층적인 통찰력을 향한 리팩터링 (1) | 2022.01.11 |
[도메인 주도 설계] 07. 언어의 사용(확장 예제) (2) (0) | 2022.01.06 |
Comments