SlideShare a Scribd company logo
1 of 30
Domain Driven Design 7장Using the Language:An Extended Example 아꿈사스터디 박일
Cargo Shipping 시스템 기본 요구사항 customer 의 cargo 를 추적할 수 있어야 한다. 미리 cargo를 예약할 수 있어야 한다. cargo가 특정 handling 상태가 되면 customer 에게 자동으로 invoice 를 보내야 한다. 여기까지 요구사항만 놓고 design 을 만들어보자.
그림 7.1
그림 7.1
model 에 나오는 객체들 Handling Event Cargo 를 배에 싣고 내리는 등의 행위 loading, unloading, being claimed 등의 상위클래스일 수 있음 Delivery Specification 목적지, 도착날짜 Cargo 에게 맡기지 않고 따로 객체를 만든 이유 Cargo 객체가 복잡해진다 LoD(Level of Detail) 을 제공 Cargo 의 목적이 Delivery Specification 이라는 걸 좀 더 분명하게 얘기할 수 있다.
model 에 나오는 객체들 role Customer 의 역할(shipper, receiver, payer…) 한 Customer 는 특정 Cargo 에 대해서 하나의 role 만 맡는다(Qualified Association) string 또는 클래스로 구현 Carrier Movement 특정 Carrier(트럭, 화물선) 가 Cargo 를 하나의 Location 에서 다른 Location 으로 이동시키는 행위
model 에 나오는 객체들 Delivery History Cargo 에 어떤 일이 있었는지에 대한 기록 Delivery History 는 마지막 Carrier Movement 로 Cargo 의 현재위치를 계산할 수 있다. 각 객체를 어떻게 찾고 저장할지를 model 에서는 다루지 않지만 design 에서는 다뤄야 한다.
Application 도입 Applications Tracking Query Booking Application Incident Logging Application application 은 coordinator 이다. 질문에 대한 답을 하는 것은 domain layer 영역
Entity,Value Object 구분 Customer : 고객, 회사이므로 상식적으로 Entity TaxID는 ID 로 부적합. Customer 는 처음 sales contact 때 ID 를 부여하고 있더라. Cargo : Entity. 실제 각 물류회사에는 Cargo 별로 ID 부여 Handling Event : Cargo 를 추적할 수 있어야 하므로 Entity Cargo ID, completion time, type 조합으로 ID 생성 Carrier Movement : shipping schedule 코드로 identity 가능 Location : 다른 지역이 이름만 같을 수 있으므로 unique ID 필요 자동증가 id 정도면 충분 Delivery History : 교환할 수 없으므로 entity. 각 Cargo 별로 History 가 다르니까 Delivery History 는 Cargo 와 1:1 관계임.  AGGREGATES 관계로 가자(Cargo 의 멤버변수) Delivery Specification 은 두 Cargo 가 같은 장소로 동시에 배송될 수 있으므로 VALUE OBJECTS Role 은 연계관계이지만, 지속성은 필요없음. VALUE OBJECT stamps, names 도 VALUE OBJECT 모델에서 중요하지 않은 속성은 대문자를 부여받지 못함 대문자를 받은 model language 는 위키페이지의 이름으로 쓸 수 있다
Shipping 에서 association 디자인 상호참조는 최대한 피하자 Customer 가 Cargo 를 레퍼런스하면귀찮을 수 있음 Customer 가 Cargo 한정으로 사용되는 것도 아님 특정한 배(Carrier)의 인벤토리를 추적한다면 Carrier Movement -> Handling Event 가 중요할 수 있지만 지금은 Cargo 만 추적하면 되므로 Handling Event  -> Carrier Movement 필요 딱 필요한 만큼만 구현할 것 환형 관계가 하나(Cargo -> Delivery History -> Handling Events -> Cargo) 있는데 가능하면 피해라. 직접 레퍼런스가 싫다면 (DB 같이 query 가 가능한) REPOSITORY 를 이용하라.
AGGREGATE 경계 Customer, Location, Carrier Movement 는 Cargo 가 공유하므로 AGGREGATE root 여야 함 Cargo 도 AGGREGATE 의 root 인데, 그 밑에 뭐가 들어갈 수 있을까? Delivery History 는 Cargo 를 통해서만 접근한다. Delivery Specification 는 VALUE OBJECT 니까 추가 Handling Events collection 이든 DB 든 Delivery History 에 대한 Handling Events 를 찾을 수 있어야 하고 특정 Carrier Movement 에 대해 load, unload 를 다 찾을 수 있어야 한다면, Handling Events 가 Cargo 에 독립적인 의미를 가지기 때문에 독자적인 AGGREGATE 의 root 가 되어야 한다. 따로 빼면 low-contention transaction 으로 만들 수 있다.
REPOSITORY 선택 AGGREGATE root 가 아니면 REPOSITORY 가 필요없음(직접 접근할 일이 없으니까). Booking Application 에서는 여러 role (shipper, receiver, ...) 을 맡을 Customer 를 선택할 수 있어야 하므로 Customer Repository 가 필요하다. Cargo 의 도착지를 지정할 수 있어야 하므로 Location Repository 도 필요하다. Activity Logging Application 는 Cargo 를 실은 Carrier Movement 를 찾아볼 수 있어야 하므로 Carrier Movement Repository필요.
Scenarios Customer 가 Cargo 의 목적지를 바꿀 수 있는가? Cargo 의 Delivery Specification 은 VALUE OBJECT 니까 덮어쓰면 된다. Repeat Business : 같은 Customer 에게 화물을 보낼 때 그전 정보를 prototype 으로 쓰고 싶다(yes24 의 이전배송정보 사용). Cargo 는 ENTITY 이자 AGGREGATE 의 root 이므로 주의 Delivery History : 비어있는 새 객체 생성 Customer Roles : Map (or collection) 을 key 와 함께 복사 key : 역할, value : Customer  Tracking ID : 새로운 Tracking ID 를 제공한다. Cargo AGGREGATE 영역 밖에는영향을 미치지 않는다
객체 생성 - Cargo public Cargo CopyPrototype(String newTrackingID) public Cargo newCargo(Cargo prototype, String newTrackingID) public Cargo newCargo(Cargo prototype) 비어있는 Delivery History 와 Delivery Specification 가 null 인 Cargo 를리턴 Delivery Specification 가 null 일 필요가 있을까? public Cargo(Stirng id) { trackingID = id; deliveryHistory = new DeliveryHistory(this); customerRoles = new HashMap();
객체 생성 - Handling Event 추가 사용자는 Incident Logging Application 로 Handling Event 를 입력한다. Handling Event 는 ENTITY 이기 때문에 생성자에 identity 에 관련된 모든 attribute 가 다 들어와야 한다. Cargo ID + completion time + event type Handling Event 는 Cargo 를 handled 라는 멤버변수로 연관관계 public HandlingEvent(Cargo c, String eventType, Date timeStamp) { 	handled = c;		// const 변수감 	type = eventType;	 // const 변수감 completionTime = timeStamp; } public static HandlingEventnewLoading( 	Cargo c, CarrierMovementloadedOnto, Date timeStamp) { HandlingEvent r = new HandlingEvent(c, LOADING_EVENT, timeStamp); r.setCarrierMovement(loadedOnto); 	return r; }
Handling Event 추가하기 복잡함
잠깐, 다른 디자인은 없을까? Handling Event 를 추가할 때 Delivery History 를 업데이트하려면 Cargo AGGREGATE 를 transaction 걸어야 한다. 다른 user 가 같은 Cargo 를 동시에 고친다면 transaction이 실패(낙관적인 lock)하거나 지연(비관적인 lock)될 수 있다. Handling Event 를 경쟁없이추가하려면 design 을 고쳐야 한다. Handling Event 를 Delivery History 의 collection 대신 query 로 바꾸면 Handling Event 를 AGGREGATE 정합성 문제없이 추가 가능 interference 없이 transaction 할 수 있다. Handling Event 의 입력이 많고 쿼리가 적다면 성능향상 가능. 그래서 Handling Event Repository 를 추가한다. findByCargoIDTimeType, findByCargoTrackingID, findByScheduleID, findMostRecentCargoIDType Handling Event Repository 에서 원하는 history 를 query 할 수 있기 때문에 Delivery History 에 persistent state 가 없어지므로 쓸모없게 된다. 다만, 하나의 Cargo 에 대한 전체 History 를 볼 일이 더 많을 경우라면 성능 trade-off 가 발생할 수 있다.
새로운 기능을 추가해보자 화물의 'type, 출발지, 목적지에 따른 화물량 예측' 기능을 Booking Application 에 통합해, 새로 booking 할 때 적합성 여부를 알고 싶다. Booking Application 은 Cargo Repository 와 Sales Management System 의 정보가 필요하다.
두 시스템 연결 Sale Management System 은 별도의 소프트웨어(시스템) Interface 로 wrap 하기 보다는 중간에 번역 레이어를 두자 Anti Corruption Layer 번역 DB -> 서버 -> 클라이언트 -> 엔진 즐겨찾기DB -> XML 전송 -> IE, Firefox 변환
Segmenting the Business Cargo 의 type 을 정의하지 않았다. ENTERPRISE SEGMENT(Analysis Patterns) a set of dimensions that define a way of breaking down a business Enterprise Segment 라는 클래스(VALUE OBJECT)가 등장 날짜, 지역등으로구분짓는 데이터(일종의 where 절, 카테고리)
지역(국가/시/도/군/면,리)/날짜/제품군
Allocation Checker Enterprise Segment 와 외부시스템의 카테고리 이름을 번역 SERVICE Booking Application 에서 하던 business rule 작업(Cargo 배치)과 Enterprise Segment 생성 책임을 Allocation Checker 으로 넘긴다. Allocation Checker 가 Enterprise Segments 로 만들 수 없는 차원은 Sales Management System 에서 쓸 수 없다는 단점이 있다
성능 문제 Sales Management System 이 외부에 있다면? Allocation Checker 에 cache 한다. COM+ 에서 interface query 하는 방식도 있다
새로운 기능 추가하기 - 정리 Sales Management System 을 Booking Application, Cargo Repository 와 통합하면서 복잡해졌지만, ANTICORRUPTION LAYER, SERVICE, ENTERPRISE SEGMENTS 를 도입하므로서 정돈되면서 도메인을 더 풍부하게 만들 수 있었다.
정리 DDD 의 모델은 요리법(recipe) 처럼 만들어야 한다. 모델만 봐도 구현할 수 있게 하되, 모델을 있는 그대로 구현하는 것이 아니라 상황에 맞게 적용할 수 있는 유연함이 필요하다. DDD 의 모델은 패턴언어와 비슷하다. 모델은 계속 같은 언어로 표현되면서 다른 모델과 관계를 맺는다.

More Related Content

What's hot

Unreal_GameAbilitySystem.pptx
Unreal_GameAbilitySystem.pptxUnreal_GameAbilitySystem.pptx
Unreal_GameAbilitySystem.pptxTonyCms
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Kwen Won Lee
 
190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁KWANGIL KIM
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해Nam Hyeonuk
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJSSandi Barr
 
Oracle R12 SCM Functional Interview Questions - Order Management
Oracle R12 SCM Functional Interview Questions - Order ManagementOracle R12 SCM Functional Interview Questions - Order Management
Oracle R12 SCM Functional Interview Questions - Order ManagementBoopathy CS
 
Oa Framework Tutorial
Oa Framework TutorialOa Framework Tutorial
Oa Framework Tutorialnolimit797
 
Multi thread game server
Multi thread game serverMulti thread game server
Multi thread game serverOnGameServer
 
Spring integration을 통해_살펴본_메시징_세계
Spring integration을 통해_살펴본_메시징_세계Spring integration을 통해_살펴본_메시징_세계
Spring integration을 통해_살펴본_메시징_세계Wangeun Lee
 
Getting Started with NgRx (Redux) Angular
Getting Started with NgRx (Redux) AngularGetting Started with NgRx (Redux) Angular
Getting Started with NgRx (Redux) AngularGustavo Costa
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템QooJuice
 
Massive service basic
Massive service basicMassive service basic
Massive service basicDaeMyung Kang
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScriptNascenia IT
 
REST API 설계
REST API 설계REST API 설계
REST API 설계Terry Cho
 
Orion Context Broker NGSI-v2 Overview for Developers That Already Know NGSI-v...
Orion Context Broker NGSI-v2 Overview for Developers That Already Know NGSI-v...Orion Context Broker NGSI-v2 Overview for Developers That Already Know NGSI-v...
Orion Context Broker NGSI-v2 Overview for Developers That Already Know NGSI-v...Fermin Galan
 
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요NAVER D2
 

What's hot (20)

Unreal_GameAbilitySystem.pptx
Unreal_GameAbilitySystem.pptxUnreal_GameAbilitySystem.pptx
Unreal_GameAbilitySystem.pptx
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표
 
190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
Oracle R12 SCM Functional Interview Questions - Order Management
Oracle R12 SCM Functional Interview Questions - Order ManagementOracle R12 SCM Functional Interview Questions - Order Management
Oracle R12 SCM Functional Interview Questions - Order Management
 
Iocp advanced
Iocp advancedIocp advanced
Iocp advanced
 
Oa Framework Tutorial
Oa Framework TutorialOa Framework Tutorial
Oa Framework Tutorial
 
Multi thread game server
Multi thread game serverMulti thread game server
Multi thread game server
 
Spring integration을 통해_살펴본_메시징_세계
Spring integration을 통해_살펴본_메시징_세계Spring integration을 통해_살펴본_메시징_세계
Spring integration을 통해_살펴본_메시징_세계
 
Database
DatabaseDatabase
Database
 
Getting Started with NgRx (Redux) Angular
Getting Started with NgRx (Redux) AngularGetting Started with NgRx (Redux) Angular
Getting Started with NgRx (Redux) Angular
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템
 
Massive service basic
Massive service basicMassive service basic
Massive service basic
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
REST API 설계
REST API 설계REST API 설계
REST API 설계
 
MVP 패턴 소개
MVP 패턴 소개MVP 패턴 소개
MVP 패턴 소개
 
RESTful Web Services
RESTful Web ServicesRESTful Web Services
RESTful Web Services
 
Orion Context Broker NGSI-v2 Overview for Developers That Already Know NGSI-v...
Orion Context Broker NGSI-v2 Overview for Developers That Already Know NGSI-v...Orion Context Broker NGSI-v2 Overview for Developers That Already Know NGSI-v...
Orion Context Broker NGSI-v2 Overview for Developers That Already Know NGSI-v...
 
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
 

Viewers also liked

Holub on Patterns 1장 전
Holub on Patterns 1장 전Holub on Patterns 1장 전
Holub on Patterns 1장 전홍준 김
 
[NHN NEXT] Java 강의 - Week4
[NHN NEXT] Java 강의 - Week4[NHN NEXT] Java 강의 - Week4
[NHN NEXT] Java 강의 - Week4Young-Ho Cho
 
즉흥연기와프로그래밍
즉흥연기와프로그래밍즉흥연기와프로그래밍
즉흥연기와프로그래밍Ryan Park
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.Ryan Park
 
AIbyExample - Ch7 raven. version 0.8
AIbyExample - Ch7 raven. version 0.8AIbyExample - Ch7 raven. version 0.8
AIbyExample - Ch7 raven. version 0.8Ryan Park
 
나도기술서번역한번해볼까 in NDC10
나도기술서번역한번해볼까 in NDC10나도기술서번역한번해볼까 in NDC10
나도기술서번역한번해볼까 in NDC10Ryan Park
 
나도(기술서)번역한번해볼까
나도(기술서)번역한번해볼까나도(기술서)번역한번해볼까
나도(기술서)번역한번해볼까Ryan Park
 
온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅Ryan Park
 
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010Ryan Park
 
Unicode 이해하기
Unicode 이해하기Unicode 이해하기
Unicode 이해하기Ryan Park
 
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10Ryan Park
 
위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점Ryan Park
 
문자셋과 인코딩
문자셋과 인코딩문자셋과 인코딩
문자셋과 인코딩Jaehoon Jung
 
Oop design principle SOLID
Oop design principle SOLIDOop design principle SOLID
Oop design principle SOLIDRyan Park
 
Oop design principle
Oop design principleOop design principle
Oop design principleRyan Park
 

Viewers also liked (20)

Holub on Patterns 1장 전
Holub on Patterns 1장 전Holub on Patterns 1장 전
Holub on Patterns 1장 전
 
[NHN NEXT] Java 강의 - Week4
[NHN NEXT] Java 강의 - Week4[NHN NEXT] Java 강의 - Week4
[NHN NEXT] Java 강의 - Week4
 
즉흥연기와프로그래밍
즉흥연기와프로그래밍즉흥연기와프로그래밍
즉흥연기와프로그래밍
 
Taocp1 2 4
Taocp1 2 4Taocp1 2 4
Taocp1 2 4
 
Unicode
UnicodeUnicode
Unicode
 
Unicode
UnicodeUnicode
Unicode
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.
 
AIbyExample - Ch7 raven. version 0.8
AIbyExample - Ch7 raven. version 0.8AIbyExample - Ch7 raven. version 0.8
AIbyExample - Ch7 raven. version 0.8
 
나도기술서번역한번해볼까 in NDC10
나도기술서번역한번해볼까 in NDC10나도기술서번역한번해볼까 in NDC10
나도기술서번역한번해볼까 in NDC10
 
나도(기술서)번역한번해볼까
나도(기술서)번역한번해볼까나도(기술서)번역한번해볼까
나도(기술서)번역한번해볼까
 
온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅
 
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
 
Unicode 이해하기
Unicode 이해하기Unicode 이해하기
Unicode 이해하기
 
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
 
위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점
 
문자셋과 인코딩
문자셋과 인코딩문자셋과 인코딩
문자셋과 인코딩
 
DDD 산책
DDD 산책DDD 산책
DDD 산책
 
Unicode100
Unicode100Unicode100
Unicode100
 
Oop design principle SOLID
Oop design principle SOLIDOop design principle SOLID
Oop design principle SOLID
 
Oop design principle
Oop design principleOop design principle
Oop design principle
 

Similar to Domain Driven Design Ch7

DDD-07-Using The Language
DDD-07-Using The LanguageDDD-07-Using The Language
DDD-07-Using The LanguageKyungryul KIM
 
구글 기술을 이용한 모바일 클라우드 애플리케이션 개발
 구글 기술을 이용한 모바일 클라우드 애플리케이션 개발 구글 기술을 이용한 모바일 클라우드 애플리케이션 개발
구글 기술을 이용한 모바일 클라우드 애플리케이션 개발LGU+
 
분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용
분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용
분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용승필 박
 
From event storming to spring cloud implementation
From event storming to spring cloud implementationFrom event storming to spring cloud implementation
From event storming to spring cloud implementationuEngine Solutions
 
Chapter3 클래스의기본(윤현성)
Chapter3 클래스의기본(윤현성)Chapter3 클래스의기본(윤현성)
Chapter3 클래스의기본(윤현성)Hyun Sung Yoon
 
Chapter3 클래스의기본(윤현성)
Chapter3 클래스의기본(윤현성)Chapter3 클래스의기본(윤현성)
Chapter3 클래스의기본(윤현성)Hyun Sung Yoon
 
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원탑크리에듀(구로디지털단지역3번출구 2분거리)
 
From event storming to spring cloud implementation
From event storming to spring cloud implementationFrom event storming to spring cloud implementation
From event storming to spring cloud implementationuEngine Solutions
 

Similar to Domain Driven Design Ch7 (9)

DDD-07-Using The Language
DDD-07-Using The LanguageDDD-07-Using The Language
DDD-07-Using The Language
 
구글 기술을 이용한 모바일 클라우드 애플리케이션 개발
 구글 기술을 이용한 모바일 클라우드 애플리케이션 개발 구글 기술을 이용한 모바일 클라우드 애플리케이션 개발
구글 기술을 이용한 모바일 클라우드 애플리케이션 개발
 
분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용
분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용
분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용
 
From event storming to spring cloud implementation
From event storming to spring cloud implementationFrom event storming to spring cloud implementation
From event storming to spring cloud implementation
 
Chapter3 클래스의기본(윤현성)
Chapter3 클래스의기본(윤현성)Chapter3 클래스의기본(윤현성)
Chapter3 클래스의기본(윤현성)
 
Chapter3 클래스의기본(윤현성)
Chapter3 클래스의기본(윤현성)Chapter3 클래스의기본(윤현성)
Chapter3 클래스의기본(윤현성)
 
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
 
From event storming to spring cloud implementation
From event storming to spring cloud implementationFrom event storming to spring cloud implementation
From event storming to spring cloud implementation
 
Redux
ReduxRedux
Redux
 

More from Ryan Park

KGC2010 - 낡은 코드에 단위테스트 넣기
KGC2010 - 낡은 코드에 단위테스트 넣기KGC2010 - 낡은 코드에 단위테스트 넣기
KGC2010 - 낡은 코드에 단위테스트 넣기Ryan Park
 
OOP 설계 원칙 S.O.L.I.D.
OOP 설계 원칙 S.O.L.I.D.OOP 설계 원칙 S.O.L.I.D.
OOP 설계 원칙 S.O.L.I.D.Ryan Park
 
프로그램은 왜 실패하는가 1장
프로그램은 왜 실패하는가 1장프로그램은 왜 실패하는가 1장
프로그램은 왜 실패하는가 1장Ryan Park
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
UnitTest, Tdd For Games Kgc2007 ParkPD
UnitTest, Tdd For Games Kgc2007 ParkPDUnitTest, Tdd For Games Kgc2007 ParkPD
UnitTest, Tdd For Games Kgc2007 ParkPDRyan Park
 
Agile Test Driven Development For Games What, Why, And How
Agile Test Driven Development For Games What, Why, And HowAgile Test Driven Development For Games What, Why, And How
Agile Test Driven Development For Games What, Why, And HowRyan Park
 
Agd Test Driven Development For Games What, Why, And How)(Game Connect 2006...
Agd   Test Driven Development For Games What, Why, And How)(Game Connect 2006...Agd   Test Driven Development For Games What, Why, And How)(Game Connect 2006...
Agd Test Driven Development For Games What, Why, And How)(Game Connect 2006...Ryan Park
 

More from Ryan Park (8)

KGC2010 - 낡은 코드에 단위테스트 넣기
KGC2010 - 낡은 코드에 단위테스트 넣기KGC2010 - 낡은 코드에 단위테스트 넣기
KGC2010 - 낡은 코드에 단위테스트 넣기
 
OOP 설계 원칙 S.O.L.I.D.
OOP 설계 원칙 S.O.L.I.D.OOP 설계 원칙 S.O.L.I.D.
OOP 설계 원칙 S.O.L.I.D.
 
Unicode
UnicodeUnicode
Unicode
 
프로그램은 왜 실패하는가 1장
프로그램은 왜 실패하는가 1장프로그램은 왜 실패하는가 1장
프로그램은 왜 실패하는가 1장
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
UnitTest, Tdd For Games Kgc2007 ParkPD
UnitTest, Tdd For Games Kgc2007 ParkPDUnitTest, Tdd For Games Kgc2007 ParkPD
UnitTest, Tdd For Games Kgc2007 ParkPD
 
Agile Test Driven Development For Games What, Why, And How
Agile Test Driven Development For Games What, Why, And HowAgile Test Driven Development For Games What, Why, And How
Agile Test Driven Development For Games What, Why, And How
 
Agd Test Driven Development For Games What, Why, And How)(Game Connect 2006...
Agd   Test Driven Development For Games What, Why, And How)(Game Connect 2006...Agd   Test Driven Development For Games What, Why, And How)(Game Connect 2006...
Agd Test Driven Development For Games What, Why, And How)(Game Connect 2006...
 

Domain Driven Design Ch7

  • 1. Domain Driven Design 7장Using the Language:An Extended Example 아꿈사스터디 박일
  • 2. Cargo Shipping 시스템 기본 요구사항 customer 의 cargo 를 추적할 수 있어야 한다. 미리 cargo를 예약할 수 있어야 한다. cargo가 특정 handling 상태가 되면 customer 에게 자동으로 invoice 를 보내야 한다. 여기까지 요구사항만 놓고 design 을 만들어보자.
  • 5. model 에 나오는 객체들 Handling Event Cargo 를 배에 싣고 내리는 등의 행위 loading, unloading, being claimed 등의 상위클래스일 수 있음 Delivery Specification 목적지, 도착날짜 Cargo 에게 맡기지 않고 따로 객체를 만든 이유 Cargo 객체가 복잡해진다 LoD(Level of Detail) 을 제공 Cargo 의 목적이 Delivery Specification 이라는 걸 좀 더 분명하게 얘기할 수 있다.
  • 6. model 에 나오는 객체들 role Customer 의 역할(shipper, receiver, payer…) 한 Customer 는 특정 Cargo 에 대해서 하나의 role 만 맡는다(Qualified Association) string 또는 클래스로 구현 Carrier Movement 특정 Carrier(트럭, 화물선) 가 Cargo 를 하나의 Location 에서 다른 Location 으로 이동시키는 행위
  • 7. model 에 나오는 객체들 Delivery History Cargo 에 어떤 일이 있었는지에 대한 기록 Delivery History 는 마지막 Carrier Movement 로 Cargo 의 현재위치를 계산할 수 있다. 각 객체를 어떻게 찾고 저장할지를 model 에서는 다루지 않지만 design 에서는 다뤄야 한다.
  • 8. Application 도입 Applications Tracking Query Booking Application Incident Logging Application application 은 coordinator 이다. 질문에 대한 답을 하는 것은 domain layer 영역
  • 9. Entity,Value Object 구분 Customer : 고객, 회사이므로 상식적으로 Entity TaxID는 ID 로 부적합. Customer 는 처음 sales contact 때 ID 를 부여하고 있더라. Cargo : Entity. 실제 각 물류회사에는 Cargo 별로 ID 부여 Handling Event : Cargo 를 추적할 수 있어야 하므로 Entity Cargo ID, completion time, type 조합으로 ID 생성 Carrier Movement : shipping schedule 코드로 identity 가능 Location : 다른 지역이 이름만 같을 수 있으므로 unique ID 필요 자동증가 id 정도면 충분 Delivery History : 교환할 수 없으므로 entity. 각 Cargo 별로 History 가 다르니까 Delivery History 는 Cargo 와 1:1 관계임. AGGREGATES 관계로 가자(Cargo 의 멤버변수) Delivery Specification 은 두 Cargo 가 같은 장소로 동시에 배송될 수 있으므로 VALUE OBJECTS Role 은 연계관계이지만, 지속성은 필요없음. VALUE OBJECT stamps, names 도 VALUE OBJECT 모델에서 중요하지 않은 속성은 대문자를 부여받지 못함 대문자를 받은 model language 는 위키페이지의 이름으로 쓸 수 있다
  • 10. Shipping 에서 association 디자인 상호참조는 최대한 피하자 Customer 가 Cargo 를 레퍼런스하면귀찮을 수 있음 Customer 가 Cargo 한정으로 사용되는 것도 아님 특정한 배(Carrier)의 인벤토리를 추적한다면 Carrier Movement -> Handling Event 가 중요할 수 있지만 지금은 Cargo 만 추적하면 되므로 Handling Event -> Carrier Movement 필요 딱 필요한 만큼만 구현할 것 환형 관계가 하나(Cargo -> Delivery History -> Handling Events -> Cargo) 있는데 가능하면 피해라. 직접 레퍼런스가 싫다면 (DB 같이 query 가 가능한) REPOSITORY 를 이용하라.
  • 11.
  • 12. AGGREGATE 경계 Customer, Location, Carrier Movement 는 Cargo 가 공유하므로 AGGREGATE root 여야 함 Cargo 도 AGGREGATE 의 root 인데, 그 밑에 뭐가 들어갈 수 있을까? Delivery History 는 Cargo 를 통해서만 접근한다. Delivery Specification 는 VALUE OBJECT 니까 추가 Handling Events collection 이든 DB 든 Delivery History 에 대한 Handling Events 를 찾을 수 있어야 하고 특정 Carrier Movement 에 대해 load, unload 를 다 찾을 수 있어야 한다면, Handling Events 가 Cargo 에 독립적인 의미를 가지기 때문에 독자적인 AGGREGATE 의 root 가 되어야 한다. 따로 빼면 low-contention transaction 으로 만들 수 있다.
  • 13.
  • 14. REPOSITORY 선택 AGGREGATE root 가 아니면 REPOSITORY 가 필요없음(직접 접근할 일이 없으니까). Booking Application 에서는 여러 role (shipper, receiver, ...) 을 맡을 Customer 를 선택할 수 있어야 하므로 Customer Repository 가 필요하다. Cargo 의 도착지를 지정할 수 있어야 하므로 Location Repository 도 필요하다. Activity Logging Application 는 Cargo 를 실은 Carrier Movement 를 찾아볼 수 있어야 하므로 Carrier Movement Repository필요.
  • 15.
  • 16. Scenarios Customer 가 Cargo 의 목적지를 바꿀 수 있는가? Cargo 의 Delivery Specification 은 VALUE OBJECT 니까 덮어쓰면 된다. Repeat Business : 같은 Customer 에게 화물을 보낼 때 그전 정보를 prototype 으로 쓰고 싶다(yes24 의 이전배송정보 사용). Cargo 는 ENTITY 이자 AGGREGATE 의 root 이므로 주의 Delivery History : 비어있는 새 객체 생성 Customer Roles : Map (or collection) 을 key 와 함께 복사 key : 역할, value : Customer Tracking ID : 새로운 Tracking ID 를 제공한다. Cargo AGGREGATE 영역 밖에는영향을 미치지 않는다
  • 17. 객체 생성 - Cargo public Cargo CopyPrototype(String newTrackingID) public Cargo newCargo(Cargo prototype, String newTrackingID) public Cargo newCargo(Cargo prototype) 비어있는 Delivery History 와 Delivery Specification 가 null 인 Cargo 를리턴 Delivery Specification 가 null 일 필요가 있을까? public Cargo(Stirng id) { trackingID = id; deliveryHistory = new DeliveryHistory(this); customerRoles = new HashMap();
  • 18. 객체 생성 - Handling Event 추가 사용자는 Incident Logging Application 로 Handling Event 를 입력한다. Handling Event 는 ENTITY 이기 때문에 생성자에 identity 에 관련된 모든 attribute 가 다 들어와야 한다. Cargo ID + completion time + event type Handling Event 는 Cargo 를 handled 라는 멤버변수로 연관관계 public HandlingEvent(Cargo c, String eventType, Date timeStamp) { handled = c; // const 변수감 type = eventType; // const 변수감 completionTime = timeStamp; } public static HandlingEventnewLoading( Cargo c, CarrierMovementloadedOnto, Date timeStamp) { HandlingEvent r = new HandlingEvent(c, LOADING_EVENT, timeStamp); r.setCarrierMovement(loadedOnto); return r; }
  • 20. 잠깐, 다른 디자인은 없을까? Handling Event 를 추가할 때 Delivery History 를 업데이트하려면 Cargo AGGREGATE 를 transaction 걸어야 한다. 다른 user 가 같은 Cargo 를 동시에 고친다면 transaction이 실패(낙관적인 lock)하거나 지연(비관적인 lock)될 수 있다. Handling Event 를 경쟁없이추가하려면 design 을 고쳐야 한다. Handling Event 를 Delivery History 의 collection 대신 query 로 바꾸면 Handling Event 를 AGGREGATE 정합성 문제없이 추가 가능 interference 없이 transaction 할 수 있다. Handling Event 의 입력이 많고 쿼리가 적다면 성능향상 가능. 그래서 Handling Event Repository 를 추가한다. findByCargoIDTimeType, findByCargoTrackingID, findByScheduleID, findMostRecentCargoIDType Handling Event Repository 에서 원하는 history 를 query 할 수 있기 때문에 Delivery History 에 persistent state 가 없어지므로 쓸모없게 된다. 다만, 하나의 Cargo 에 대한 전체 History 를 볼 일이 더 많을 경우라면 성능 trade-off 가 발생할 수 있다.
  • 21.
  • 22. 새로운 기능을 추가해보자 화물의 'type, 출발지, 목적지에 따른 화물량 예측' 기능을 Booking Application 에 통합해, 새로 booking 할 때 적합성 여부를 알고 싶다. Booking Application 은 Cargo Repository 와 Sales Management System 의 정보가 필요하다.
  • 23. 두 시스템 연결 Sale Management System 은 별도의 소프트웨어(시스템) Interface 로 wrap 하기 보다는 중간에 번역 레이어를 두자 Anti Corruption Layer 번역 DB -> 서버 -> 클라이언트 -> 엔진 즐겨찾기DB -> XML 전송 -> IE, Firefox 변환
  • 24. Segmenting the Business Cargo 의 type 을 정의하지 않았다. ENTERPRISE SEGMENT(Analysis Patterns) a set of dimensions that define a way of breaking down a business Enterprise Segment 라는 클래스(VALUE OBJECT)가 등장 날짜, 지역등으로구분짓는 데이터(일종의 where 절, 카테고리)
  • 25.
  • 27. Allocation Checker Enterprise Segment 와 외부시스템의 카테고리 이름을 번역 SERVICE Booking Application 에서 하던 business rule 작업(Cargo 배치)과 Enterprise Segment 생성 책임을 Allocation Checker 으로 넘긴다. Allocation Checker 가 Enterprise Segments 로 만들 수 없는 차원은 Sales Management System 에서 쓸 수 없다는 단점이 있다
  • 28. 성능 문제 Sales Management System 이 외부에 있다면? Allocation Checker 에 cache 한다. COM+ 에서 interface query 하는 방식도 있다
  • 29. 새로운 기능 추가하기 - 정리 Sales Management System 을 Booking Application, Cargo Repository 와 통합하면서 복잡해졌지만, ANTICORRUPTION LAYER, SERVICE, ENTERPRISE SEGMENTS 를 도입하므로서 정돈되면서 도메인을 더 풍부하게 만들 수 있었다.
  • 30. 정리 DDD 의 모델은 요리법(recipe) 처럼 만들어야 한다. 모델만 봐도 구현할 수 있게 하되, 모델을 있는 그대로 구현하는 것이 아니라 상황에 맞게 적용할 수 있는 유연함이 필요하다. DDD 의 모델은 패턴언어와 비슷하다. 모델은 계속 같은 언어로 표현되면서 다른 모델과 관계를 맺는다.