SlideShare a Scribd company logo
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 EventCargo 를 배에 싣고 내리는 등의 행위loading, unloading, being claimed 등의 상위클래스일 수 있음Delivery Specification목적지, 도착날짜Cargo 에게 맡기지 않고 따로 객체를 만든 이유Cargo 객체가 복잡해진다LoD(Level of Detail) 을 제공Cargo 의 목적이 Delivery Specification 이라는 걸 좀 더 분명하게 얘기할 수 있다.
model 에 나오는 객체들roleCustomer 의 역할(shipper, receiver, payer…)한 Customer 는 특정 Cargo 에 대해서 하나의 role 만 맡는다(Qualified Association)string 또는 클래스로 구현Carrier Movement특정 Carrier(트럭, 화물선) 가 Cargo 를 하나의 Location 에서 다른 Location 으로 이동시키는 행위
model 에 나오는 객체들Delivery HistoryCargo 에 어떤 일이 있었는지에 대한 기록Delivery History 는 마지막 Carrier Movement 로 Cargo 의 현재위치를 계산할 수 있다.각 객체를 어떻게 찾고 저장할지를 model 에서는 다루지 않지만 design 에서는 다뤄야 한다.
Application 도입ApplicationsTracking QueryBooking ApplicationIncident Logging Applicationapplication 은 coordinator 이다. 질문에 대한 답을 하는 것은 domain layer 영역
Entity,Value Object 구분Customer : 고객, 회사이므로 상식적으로 EntityTaxID는 ID 로 부적합. Customer 는 처음 sales contact 때 ID 를 부여하고 있더라.Cargo : Entity. 실제 각 물류회사에는 Cargo 별로 ID 부여Handling Event : Cargo 를 추적할 수 있어야 하므로 EntityCargo 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 OBJECTSRole 은 연계관계이지만, 지속성은 필요없음. VALUE OBJECTstamps, 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 를 이용하라.
Domain Driven Design Ch7
AGGREGATE 경계Customer, Location, Carrier Movement 는 Cargo 가 공유하므로 AGGREGATE root 여야 함Cargo 도 AGGREGATE 의 root 인데, 그 밑에 뭐가 들어갈 수 있을까?Delivery History 는 Cargo 를 통해서만 접근한다.Delivery Specification 는 VALUE OBJECT 니까 추가Handling Eventscollection 이든 DB 든 Delivery History 에 대한 Handling Events 를 찾을 수 있어야 하고특정 Carrier Movement 에 대해 load, unload 를 다 찾을 수 있어야 한다면, Handling Events 가 Cargo 에 독립적인 의미를 가지기 때문에 독자적인 AGGREGATE 의 root 가 되어야 한다.따로 빼면 low-contention transaction 으로 만들 수 있다.
Domain Driven Design Ch7
REPOSITORY 선택AGGREGATE root 가 아니면 REPOSITORY 가 필요없음(직접 접근할 일이 없으니까).Booking Application 에서는 여러 role (shipper, receiver, ...) 을 맡을 Customer 를 선택할 수 있어야 하므로 Customer Repository 가 필요하다.Cargo 의 도착지를 지정할 수 있어야 하므로 Location Repository 도 필요하다.Activity Logging Application 는 Cargo 를 실은 Carrier Movement 를 찾아볼 수 있어야 하므로 Carrier Movement Repository필요.
Domain Driven Design Ch7
ScenariosCustomer 가 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 영역 밖에는영향을 미치지 않는다
객체 생성 - Cargopublic 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 typeHandling 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, findMostRecentCargoIDTypeHandling Event Repository 에서 원하는 history 를 query 할 수 있기 때문에 Delivery History 에 persistent state 가 없어지므로 쓸모없게 된다.다만, 하나의 Cargo 에 대한 전체 History 를 볼 일이 더 많을 경우라면 성능 trade-off 가 발생할 수 있다.
Domain Driven Design Ch7
새로운 기능을 추가해보자화물의 '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 BusinessCargo 의 type 을 정의하지 않았다.ENTERPRISE SEGMENT(Analysis Patterns)a set of dimensions that define a way of breaking down a businessEnterprise Segment 라는 클래스(VALUE OBJECT)가 등장날짜, 지역등으로구분짓는 데이터(일종의 where 절, 카테고리)
Domain Driven Design Ch7
지역(국가/시/도/군/면,리)/날짜/제품군
Allocation CheckerEnterprise Segment 와 외부시스템의 카테고리 이름을 번역SERVICEBooking 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

PPTX
Domain driven design 8장
PDF
도메인 주도 설계 - 16 대규모 구조
PPTX
9장 도메인 주도 설계
PPTX
도메인 주도 설계 - 6장 도메인 객체의 생명주기
PPTX
PDF
Clean pragmatic architecture @ devflix
PPSX
Domain Driven Design
PPTX
Micro Front-End & Microservices - Plansoft
Domain driven design 8장
도메인 주도 설계 - 16 대규모 구조
9장 도메인 주도 설계
도메인 주도 설계 - 6장 도메인 객체의 생명주기
Clean pragmatic architecture @ devflix
Domain Driven Design
Micro Front-End & Microservices - Plansoft

What's hot (20)

PPTX
Introduction to DDD
PPTX
Domain Driven Design
PDF
A Separation of Concerns: Clean Architecture on Android
PDF
아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델
PDF
Domain driven design and model driven development
PPTX
OOP 설계 원칙 S.O.L.I.D.
PDF
Asynchronous API in Java8, how to use CompletableFuture
PPTX
The Art of Clean code
PPSX
SOLID Principles and The Clean Architecture
PDF
이벤트 기반 분산 시스템을 향한 여정
PDF
Real Life Clean Architecture
PPTX
Functional Patterns with Java8 @Bucharest Java User Group
PDF
Code Smells and Its type (With Example)
PPTX
Angular Best Practices To Build Clean and Performant Web Applications
PPTX
Code smell overview
PPTX
Clean Pragmatic Architecture - Avoiding a Monolith
PDF
Clean Architecture
PDF
DDD 구현기초 (거의 Final 버전)
PDF
Docker Introduction
PPTX
A Practical Guide to Domain Driven Design: Presentation Slides
Introduction to DDD
Domain Driven Design
A Separation of Concerns: Clean Architecture on Android
아꿈사 DDD(Domain-Driven Design) 5장 소프트웨어에서 표현되는 모델
Domain driven design and model driven development
OOP 설계 원칙 S.O.L.I.D.
Asynchronous API in Java8, how to use CompletableFuture
The Art of Clean code
SOLID Principles and The Clean Architecture
이벤트 기반 분산 시스템을 향한 여정
Real Life Clean Architecture
Functional Patterns with Java8 @Bucharest Java User Group
Code Smells and Its type (With Example)
Angular Best Practices To Build Clean and Performant Web Applications
Code smell overview
Clean Pragmatic Architecture - Avoiding a Monolith
Clean Architecture
DDD 구현기초 (거의 Final 버전)
Docker Introduction
A Practical Guide to Domain Driven Design: Presentation Slides
Ad

Viewers also liked (20)

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

Similar to Domain Driven Design Ch7 (20)

PDF
DDD-07-Using The Language
PDF
DDD start 1장
PDF
Ddd start 부록 지앤선&ksug
PDF
MSA_기초자료.pdf
PPTX
Event Storming and Implementation Workshop
PPTX
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
PDF
DDD로 복잡함 다루기
PDF
Event storming based msa training commerce example v2
PDF
Event storming based msa training commerce example
PDF
Event Storming(이벤트 스토밍)
PPTX
도메인주도설계
PDF
Jpa 쿼리 포함 자료
PDF
Jpa 쿼리 포함 자료
PPTX
도메인 객체의 생명주기
PDF
[AWSKRUG] 데이터 얼마까지 알아보셨어요?
PDF
Event storming based msa training commerce example add_handson_v3
PDF
Beginning the UML - in Banking Domain (UML 교육자료)
PPTX
분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용
PDF
도메인구현 KSUG 20151128
PDF
객체지향의 사실과 오해 7장.함께모으기
DDD-07-Using The Language
DDD start 1장
Ddd start 부록 지앤선&ksug
MSA_기초자료.pdf
Event Storming and Implementation Workshop
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
DDD로 복잡함 다루기
Event storming based msa training commerce example v2
Event storming based msa training commerce example
Event Storming(이벤트 스토밍)
도메인주도설계
Jpa 쿼리 포함 자료
Jpa 쿼리 포함 자료
도메인 객체의 생명주기
[AWSKRUG] 데이터 얼마까지 알아보셨어요?
Event storming based msa training commerce example add_handson_v3
Beginning the UML - in Banking Domain (UML 교육자료)
분산 트랜잭션 환경에서 데이터 일관성 유지 방안 업로드용
도메인구현 KSUG 20151128
객체지향의 사실과 오해 7장.함께모으기

More from Ryan Park (8)

PDF
KGC2010 - 낡은 코드에 단위테스트 넣기
PPTX
Unicode
PDF
Oop design principle
PPTX
프로그램은 왜 실패하는가 1장
PPT
Working Effectively With Legacy Code - xp2005
PDF
UnitTest, Tdd For Games Kgc2007 ParkPD
PPT
Agile Test Driven Development For Games What, Why, And How
PPT
Agd Test Driven Development For Games What, Why, And How)(Game Connect 2006...
KGC2010 - 낡은 코드에 단위테스트 넣기
Unicode
Oop design principle
프로그램은 왜 실패하는가 1장
Working Effectively With Legacy Code - xp2005
UnitTest, Tdd For Games Kgc2007 ParkPD
Agile Test Driven Development For Games What, Why, And How
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 EventCargo 를 배에 싣고 내리는 등의 행위loading, unloading, being claimed 등의 상위클래스일 수 있음Delivery Specification목적지, 도착날짜Cargo 에게 맡기지 않고 따로 객체를 만든 이유Cargo 객체가 복잡해진다LoD(Level of Detail) 을 제공Cargo 의 목적이 Delivery Specification 이라는 걸 좀 더 분명하게 얘기할 수 있다.
  • 6. model 에 나오는 객체들roleCustomer 의 역할(shipper, receiver, payer…)한 Customer 는 특정 Cargo 에 대해서 하나의 role 만 맡는다(Qualified Association)string 또는 클래스로 구현Carrier Movement특정 Carrier(트럭, 화물선) 가 Cargo 를 하나의 Location 에서 다른 Location 으로 이동시키는 행위
  • 7. model 에 나오는 객체들Delivery HistoryCargo 에 어떤 일이 있었는지에 대한 기록Delivery History 는 마지막 Carrier Movement 로 Cargo 의 현재위치를 계산할 수 있다.각 객체를 어떻게 찾고 저장할지를 model 에서는 다루지 않지만 design 에서는 다뤄야 한다.
  • 8. Application 도입ApplicationsTracking QueryBooking ApplicationIncident Logging Applicationapplication 은 coordinator 이다. 질문에 대한 답을 하는 것은 domain layer 영역
  • 9. Entity,Value Object 구분Customer : 고객, 회사이므로 상식적으로 EntityTaxID는 ID 로 부적합. Customer 는 처음 sales contact 때 ID 를 부여하고 있더라.Cargo : Entity. 실제 각 물류회사에는 Cargo 별로 ID 부여Handling Event : Cargo 를 추적할 수 있어야 하므로 EntityCargo 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 OBJECTSRole 은 연계관계이지만, 지속성은 필요없음. VALUE OBJECTstamps, 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 를 이용하라.
  • 12. AGGREGATE 경계Customer, Location, Carrier Movement 는 Cargo 가 공유하므로 AGGREGATE root 여야 함Cargo 도 AGGREGATE 의 root 인데, 그 밑에 뭐가 들어갈 수 있을까?Delivery History 는 Cargo 를 통해서만 접근한다.Delivery Specification 는 VALUE OBJECT 니까 추가Handling Eventscollection 이든 DB 든 Delivery History 에 대한 Handling Events 를 찾을 수 있어야 하고특정 Carrier Movement 에 대해 load, unload 를 다 찾을 수 있어야 한다면, Handling Events 가 Cargo 에 독립적인 의미를 가지기 때문에 독자적인 AGGREGATE 의 root 가 되어야 한다.따로 빼면 low-contention transaction 으로 만들 수 있다.
  • 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필요.
  • 16. ScenariosCustomer 가 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. 객체 생성 - Cargopublic 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 typeHandling 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, findMostRecentCargoIDTypeHandling Event Repository 에서 원하는 history 를 query 할 수 있기 때문에 Delivery History 에 persistent state 가 없어지므로 쓸모없게 된다.다만, 하나의 Cargo 에 대한 전체 History 를 볼 일이 더 많을 경우라면 성능 trade-off 가 발생할 수 있다.
  • 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 BusinessCargo 의 type 을 정의하지 않았다.ENTERPRISE SEGMENT(Analysis Patterns)a set of dimensions that define a way of breaking down a businessEnterprise Segment 라는 클래스(VALUE OBJECT)가 등장날짜, 지역등으로구분짓는 데이터(일종의 where 절, 카테고리)
  • 27. Allocation CheckerEnterprise Segment 와 외부시스템의 카테고리 이름을 번역SERVICEBooking 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 의 모델은 패턴언어와 비슷하다. 모델은 계속 같은 언어로 표현되면서 다른 모델과 관계를 맺는다.