DOMAIN MODEL 패턴과 JPA의 조화객체지향적인 도메인 레이어 구축하기조영호NHN 커머스개발센터Eternity’s Chit-Chat(http://aeternum.egloos.com)
목차1. 온라인 영화 예매 시스템 도메인2. 임피던스 불일치Impedance Mismatch3. JPAJava Persistence API4. 결롞
1. 온라인 영화 예매 시스템 도메인
Domain Concept - 영화             Movie    4 / 객체지향적인 도메인 레이어 구축하기
Domain Concept - 상영                                         2011-10-18 09:30 조조          Showing                          ...
Domain Concept – 할인 정책         Discount                 Amount Discount                                 8,000 - 800 = 7,20...
Domain Concept – 할인 규칙                                 Sequence Rule             Rule                             조조 상영인 경...
Domain Concept –할인 정책 + 할인 규칙                                                        조조 상영인 경우                            ...
Domain Concept –예매        Reservation                              제   목   도가니                                      2011년 ...
Domain Model        Showing                       Reservation                       1       0..*               0..*       ...
영화 예매 책임 수행을 위한 협력의 설계 후보 객체Candidate, 책임Responsibility, 협력Collaboration 식별                                              ...
도메인 레이어 객체 구현                                                                                      User Interface         ...
Domain Model        Showing                       Reservation                       1       0..*               0..*       ...
Domain Layer Design & Domain Model              Showing                                            Reservation            ...
아키텍처 패턴                             User Interface                             Service                             Domain ...
2. 임피던스 불일치Impedance Mismatch
임피던스 불일치Impedance Mismatch    17 / 객체지향적인 도메인 레이어 구축하기
객체-관계 임피던스 불일치 객체 모델과 DB 스키마 간의 불일치 객체 패러다임Object Paradigm과 관계 패러다임Relational Paradigm 간의 불일치                           ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch    구성 요소 크기Granularity의 불일치                                                    MOVIE                             ...
Entity & Value Object   Identity                                                 Value                                    ...
책임의 재사용                             Money                             금액과 환율을 알고 있다       Movie                 금액을 +,-,*,...
Problem     코드 중복Code Duplication                                                                                         ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch        데이터베이스 식별자Database Identity 테이블 주키Primary Key                제목                                        제목...
객체 식별자Object Identity Java == 연산자                               제목                           제목                          ...
Problem        데이터베이스-객체 식별자 불일치Identity Mismatch     MOVIE          ID                  TITLE   RUNNING_TIME   FEE_AMOUNT...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch    다형성Polymorphism                                                                                    {abstract} ...
Problem     젃차적인 조건 분기Conditional Branch                                                                                  ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch    데이터베이스 외래키Foreign Key                                              MOVIE                                 SHOWI...
테이블 외래키Foreign Key - 양방향BiDirectional                               MOVIE          SHOWING                               I...
객체 연관관계Association – 단방향UniDirectional                                      MOVIE                      SHOWING            ...
객체 협력Collaboration을 통한 구현   연관 관계는 책임 분배와 협력을 위한 핵심 메커니즘  Showing                                                        ...
Problem            Data + Process = 젃차적인Procedural 프로그래밍                                          MOVIE                   ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch                캡슐화Encapsulation                                                                                  ...
할인 규칙 등록                                                                                           {abstract}             ...
Problem     캡슐화 저해               Flat                     불변식 위반Invariant Violation                               Movie mo...
Conclusion     임피던스 불일치의 결과 Anemic Domain Model & Fat Service Layer        public class Movie {                     publi...
아키텍처 패턴                             User Interface                             Service                             Domain ...
3. JPAJava Persistence API
DATA MAPPER 객체 모델과 DB 스키마 간의 독립성 유지 도메인 객체는 DB에 대해 독립적 ORMObject-Relational Mapper                                     ...
JPAJava Persistence API Java ORM 표준 명세 Annotation과 XML을 이용한 META DATA MAPPING 기능 제공 Hibernate, EclipseLink             ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch    구성 요소 크기Granularity의 불일치                                                                MOVIE                 ...
Solution      @Embeddable                                                                              Value Object       ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch        식별자 불일치Identity Mismatch      MOVIE           ID                  TITLE   RUNNING_TIME   FEE_AMOUNT       ...
Solution       영속 컨텍스트Persistence Context                                                          Begin   Commit/        ...
영화 엔티티Entity 조회    MOVIE        ID                  TITLE   RUNNING_TIME   FEE_AMOUNT              FEE_CURRENCY         1 ...
영속 컨텍스트Persistence Context                                                                      Begin      Commit/        ...
첫 번째 영화 엔티티 다시 조회    MOVIE        ID                  TITLE   RUNNING_TIME   FEE_AMOUNT              FEE_CURRENCY         ...
영속 컨텍스트Persistence Context                                                                     Begin      Commit/        U...
식별자 일관성 보장 데이터베이스 주키Primary Key와 객체 식별자Identity 간 일관성 유지     MOVIE         ID                  TITLE   RUNNING_TIME   FEE...
식별자 일관성 보장        movie1 = entityManager.load(Movie.class, 1);        movie2 = entityManager.load(Movie.class, 1);        ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch    다형성Polymorphism                                                                                {abstract}     ...
Solution        상속 매핑Inheritance Mapping                                                           {abstract}             ...
Solution     다형성을 통한 조건 분기 제거                                                                                     {abstrac...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch         연관관계Association와 외래키Foreign Key                                     MOVIE                      SHOWING   ...
Solution     외래키 맵핑Foreign Key Mapping                                 MOVIE                          SHOWING             ...
임피던스 불일치 유형          구성 요소 크기Granularity의 불일치          식별자Identity의 불일치          다형성Polymorphism의 불일치          연관 관계Associ...
Mismatch                               캡슐화Encapsulation                                                                   ...
Solution          페치 젂략Fetch Strategy 지연 페치Lazy Fetch           public class Movie {             @OneToOne(cascade=Cascad...
Solution          페치 젂략Fetch Strategy 선행 페치Eager Fetch           public class Movie {             @OneToOne(cascade=Casca...
Solution     Aggregate = 캡슐화 경계Encapsulation Boundary 예기치 못한 변경으로부터 보호 객체 그룹의 불변성 보장                          Showing   ...
4. 결롞
DOMAIN MODEL PATTERN 도메인을 구성하는 개념들을 따르는 도메인 레이어 적젃한 책임의 분배와 협력을 통한 객체 지향적인 도메인 레이어   72 / 객체지향적인 도메인 레이어 구축하기
임피던스 불일치 맹목적으로 테이블의 구조를 따르는 객체 구조 젃차적인 TRANSACTION SCRIPT로 향하는 한 가지 이유    73 / 객체지향적인 도메인 레이어 구축하기
JPAJavaPersistece API 임피던스 불일치를 해결할 수 있는 실용적인 솔루션 풍부한 도메인 레이어Rich Domain Layer의 기반      74 / 객체지향적인 도메인 레이어 구축하기
Domain Model에 초점을 맞춰라              Showing                                            Reservation                         ...
Data Model이 더 중요   76 / 객체지향적인 도메인 레이어 구축하기
타협하라                    Be Pragmatic  데이터베이스가 하나의 객체 저장소로 보여진다면 매핑 도구의 기능과는 상관없이 데이터  모델과 객체 모델이 서로 갈라지게 해서는 안 된다. 일부 객체 관...
Thank you.78 / 객체지향적인 도메인 레이어 구축하기
Question?79 / 객체지향적인 도메인 레이어 구축하기
참고자료- Christian Bauer, Gavin King, Java Persistence with Hibernate, Manning, 2006.- Michael Keith, Merrick Schincario, Pro...
Appendix A.  CRC Card
예매 생성 책임 예매 생성에 필요한 정보의 EXPERT에게 할당Creator Showing 상영 정보를 알고 있다 예매 정보를 생성한다    82 / 객체지향적인 도메인 레이어 구축하기
가격 계산 책임 영화 가격 정보를 알고 있는 EXPERT에 할당Information Expert                                      Movie Showing                 ...
할인율 계산 책임 할인율을 적용할 STRATEGY 객체 추가                               Movie Showing                       영화 정보를 알고 있다     Disc...
할인 여부를 판단할 책임 할인 정책을 판단하기 위한 SPECIFICATION 객체 추가                               Movie Showing                       영화 정보를...
Appendix B.  Domain Model Pattern Implementation
Domain Layer Collaborationpublic class Showing {  public Reservation reserve(Customer customer, int audienceCount) {    re...
Domain Layer Collaborationpublic abstract class DiscountStrategy {  public Money calculateFee(Showing showing) {    for(Ru...
Domain Layer Collaborationpublic abstract class DiscountStrategy {  public Money calculateFee(Showing showing) {    for(Ru...
Domain Layer Collaboration               :Showing               :Reservation                    :Movie                    ...
Data Model     RESERVATION               CUSTOMER      ID                        ID      CUSTOMER_ID(FK)           CUSTOME...
Appendix C.  Impedance Mismatch Summary
임피던스 불일치Impedance Mismatch                                                              MOVIE                             ...
Upcoming SlideShare
Loading in …5
×

A6 객체지향적인 도메인 레이어 구축하기

3,014 views

Published on

0 Comments
16 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,014
On SlideShare
0
From Embeds
0
Number of Embeds
91
Actions
Shares
0
Downloads
115
Comments
0
Likes
16
Embeds 0
No embeds

No notes for slide

A6 객체지향적인 도메인 레이어 구축하기

  1. 1. DOMAIN MODEL 패턴과 JPA의 조화객체지향적인 도메인 레이어 구축하기조영호NHN 커머스개발센터Eternity’s Chit-Chat(http://aeternum.egloos.com)
  2. 2. 목차1. 온라인 영화 예매 시스템 도메인2. 임피던스 불일치Impedance Mismatch3. JPAJava Persistence API4. 결롞
  3. 3. 1. 온라인 영화 예매 시스템 도메인
  4. 4. Domain Concept - 영화 Movie 4 / 객체지향적인 도메인 레이어 구축하기
  5. 5. Domain Concept - 상영 2011-10-18 09:30 조조 Showing 2011-10-21 20:30 5회 2011-12-01 14:20 4회 5 / 객체지향적인 도메인 레이어 구축하기
  6. 6. Domain Concept – 할인 정책 Discount Amount Discount 8,000 - 800 = 7,200 Percent Discount 8,000 – (8,000 * 0.1) = 7,200 6 / 객체지향적인 도메인 레이어 구축하기
  7. 7. Domain Concept – 할인 규칙 Sequence Rule Rule 조조 상영인 경우 10회 상영인 경우 Time Rule 월요일 10:00 ~ 12:00 상영인 경우 화요일 18:00 ~ 21:00 상영인 경우 7 / 객체지향적인 도메인 레이어 구축하기
  8. 8. Domain Concept –할인 정책 + 할인 규칙 조조 상영인 경우 10회 상영인 경우 도가니 Amount DC 8000원 800원 월요일 10:00 ~ 12:00 상영인 경우 화요일 18:00 ~ 21:00 상영인 경우 Movie Discount Rule 1 0..1 1 1..* 8 / 객체지향적인 도메인 레이어 구축하기
  9. 9. Domain Concept –예매 Reservation 제 목 도가니 2011년 10월 18일 (목) 상영 정보 7회 6:00(오후) – 8:00(오후) 인 원 2명 정 가 16,000원 결재 금액 14,400원 9 / 객체지향적인 도메인 레이어 구축하기
  10. 10. Domain Model Showing Reservation 1 0..* 0..* 1 1 0..1 1 1..* Movie Discount Rule 10 / 객체지향적인 도메인 레이어 구축하기
  11. 11. 영화 예매 책임 수행을 위한 협력의 설계 후보 객체Candidate, 책임Responsibility, 협력Collaboration 식별 Movie Showing 영화 정보를 알고 있다 Discount Strategy 가격을 계산한다 상영 정보를 알고 있다 Movie 예매 정보를 생성한다 DiscountStrategy 할인율 정책을 알고 있다 Rule 할인된 가격을 계산한다 Rule 할인 정책을 알고 있다 Showing 할인 여부를 판단한다 11 / 객체지향적인 도메인 레이어 구축하기
  12. 12. 도메인 레이어 객체 구현 User Interface Service Reservation Domain Showing <<create>> Infrastructure reserve(customer, count):Reservation Customer {abstract} {abstract} Movie DiscountStrategy Rule calculateFee(showing):Money calculateFee(showing):Money isStatisfiedBy(showing):boolean Amount Percent NonDiscount Sequence TimeOfDay Strategy Strategy Strategy Rule Rule 12 / 객체지향적인 도메인 레이어 구축하기
  13. 13. Domain Model Showing Reservation 1 0..* 0..* 1 1 0..1 1 1..* Movie Discount Rule 13 / 객체지향적인 도메인 레이어 구축하기
  14. 14. Domain Layer Design & Domain Model Showing Reservation Reservation Showing 1 <<create>> 0..* reserve(customer, count):Reservation Customer 0..* {abstract} {abstract} Movie DiscountStrategy Rule 1 calculateFee(showing):Money calculateFee(showing):Money isStatisfiedBy(showing):boolean 1 0..1 1 1..* Amount Percent NonDiscount Sequence TimeOfDay Strategy Strategy Strategy Rule Rule Movie Discount Rule 14 / 객체지향적인 도메인 레이어 구축하기
  15. 15. 아키텍처 패턴 User Interface Service Domain Infrastructure Domain Model 15 / 객체지향적인 도메인 레이어 구축하기
  16. 16. 2. 임피던스 불일치Impedance Mismatch
  17. 17. 임피던스 불일치Impedance Mismatch 17 / 객체지향적인 도메인 레이어 구축하기
  18. 18. 객체-관계 임피던스 불일치 객체 모델과 DB 스키마 간의 불일치 객체 패러다임Object Paradigm과 관계 패러다임Relational Paradigm 간의 불일치 RULE DISCOUNT DiscountStrategy Rule ID MOVIE_ID(FK) DISCOUNT_ID(FK) DISCOUNT_TYPE POSITION FEE_AMOUNT RULE_TYPE FEE_CURRENCY DAY_OF_WEEK Amount Percent NonDiscount Sequence TimeOfDay PERCENT START_TIME Strategy Strategy Strategy Rule Rule END_TUME SEQUENCE 18 / 객체지향적인 도메인 레이어 구축하기
  19. 19. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 19 / 객체지향적인 도메인 레이어 구축하기
  20. 20. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 20 / 객체지향적인 도메인 레이어 구축하기
  21. 21. Mismatch 구성 요소 크기Granularity의 불일치 MOVIE ID(PK) TITLE RUNNING_TIME Movie FEE_AMOUNT FEE_CURRENCY 제목 하나와 앨리스 시간 135분 <<value object>> running Duration Time 요금 quantity <<entity>> 8,000원 Movie title <<value object>> calculateFee(showing):Money Money amount currency fee 21 / 객체지향적인 도메인 레이어 구축하기
  22. 22. Entity & Value Object Identity Value Value Object Entity <<value object>> running Duration Time quantity <<entity>> Movie title <<value object>> calculateFee(showing):Money Money amount currency fee 22 / 객체지향적인 도메인 레이어 구축하기
  23. 23. 책임의 재사용 Money 금액과 환율을 알고 있다 Movie 금액을 +,-,*,/한다 영화 정보를 알고 있다 가격을 계산한다 Duration 기간을 알고 있다. 기간의 합, 차를 계산한다 23 / 객체지향적인 도메인 레이어 구축하기
  24. 24. Problem 코드 중복Code Duplication RESERVATION MOVIE ID(PK) ID(PK) CUSTOMER_ID(FK) TITLE SHOWING_ID(FK) RUNNING_TIME FEE_AMOUNT FEE_AMOUNT FEE_CURRENCY FEE_CURRENCY AUDIENCE_COUNT class Movie { long plus(long fee, Currency currency) { if (this.feeCurrency.equals(currency) { return this.fee + fee; } Movie throw new IllegalArgumentException(); Reservation } id } id title customerId runningTime showingId fee class Reservation { amount long add(long amount, Currency currency) { feeCurrency acmointCurrency if (this.amountCurrency.equals(currency) { return this.amount + fee; audienceCount calculateFee() } getFee() throw new IllegalArgumentException(); } } 24 / 객체지향적인 도메인 레이어 구축하기
  25. 25. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 25 / 객체지향적인 도메인 레이어 구축하기
  26. 26. Mismatch 데이터베이스 식별자Database Identity 테이블 주키Primary Key 제목 제목 시간을 시간을 달리는 소녀 달리는 소녀 시간 시간 95분 95분 요금 요금 8,000원 8,000원 MOVIE ID TITLE RUNNING_TIME FEE_AMOUNT FEE_CURRENCY 1 시간을 달리는 소녀 95 8,000 KRW 2 시간을 달리는 소녀 95 8,000 KRW 26 / 객체지향적인 도메인 레이어 구축하기
  27. 27. 객체 식별자Object Identity Java == 연산자 제목 제목 시간을 시간을 달리는 소녀 달리는 소녀 시간 시간 95분 95분 요금 요금 8,000원 8,000원 address 1 address 2 movie1 : Movie movie2 : Movie title = ‚시간을 달리는 소녀‛ title = ‚시간을 달리는 소녀‛ runningTime = 95 runningTime = 95 Fee = 8000 Fee = 8000 27 / 객체지향적인 도메인 레이어 구축하기
  28. 28. Problem 데이터베이스-객체 식별자 불일치Identity Mismatch MOVIE ID TITLE RUNNING_TIME FEE_AMOUNT FEE_CURRENCY 1 시간을 달리는 소녀 95 8,000 KRW 2 시간을 달리는 소녀 95 8,000 KRW movie1 : Movie movie2 : Movie title = ‚시간을 달리는 소녀‛ title = ‚시간을 달리는 소녀‛ runningTime = 95 runningTime = 95 Fee = 8000 Fee = 8000 28 / 객체지향적인 도메인 레이어 구축하기
  29. 29. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 29 / 객체지향적인 도메인 레이어 구축하기
  30. 30. Mismatch 다형성Polymorphism {abstract} Movie DiscountStrategy Movie Discount calculateFee(showing) registerDate calculateFee(showing) Amount Discount 800원 Amount Percent Non DiscountStrategy DiscountStrategy DiscountStrategy Percent Discount 10% discountAmount percent public class Movie { No Discount 0원(%) private DiscountStrategy discountStrategy; public Money calculateFee(Showing showing) { return discountStrategy.calculateFee(showing); } } 30 / 객체지향적인 도메인 레이어 구축하기
  31. 31. Problem 젃차적인 조건 분기Conditional Branch {abstract} Movie Movie DiscountStrategy DiscountStrategy id movieId Movie Discount calculateFee(showing) title registerDate discountType runningTime calculateFee(showing) amount fee percent Amount Discount 800원 feeCurrency registerDate calculateFee() calculateFee() Amount Percent Non DiscountStrategy DiscountStrategy DiscountStrategy Percent Discount 10% discountAmount percent public class ReservationService { public class Movie { public Money calculateFee(Movie movie, No Discount 0원(%) private DiscountStrategy discountStrategy) { DiscountStrategy discountStrategy; if (discountStrategy.isAmountType()) { ... public Money calculateFee(Showing showing) { } else if (discountStrategy.isPercentType()) { return discountStrategy.calculateFee(showing); } ... } else { } ... } ... } } 31 / 객체지향적인 도메인 레이어 구축하기
  32. 32. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 32 / 객체지향적인 도메인 레이어 구축하기
  33. 33. Mismatch 데이터베이스 외래키Foreign Key MOVIE SHOWING ID(PK) ID(PK) TITLE MOVIE_ID(FK) RUNNING_TIME SEQUENCE Movie Showing FEE_AMOUNT SHOWING_TIME FEE_CURRENCY 1회 10/18 10:00 2회 10/18 12:30 MOVIE 3회 ID TITLE 10/18 15:00 1 하나와 앨리스 4회 10/18 17:30 SHOWING ID MOVIE_ID SEQUENCE SHOWING_TIME 1 1 7 2010-12-23 18:00 33 / 객체지향적인 도메인 레이어 구축하기
  34. 34. 테이블 외래키Foreign Key - 양방향BiDirectional MOVIE SHOWING ID(PK) ID(PK) TITLE MOVIE_ID(FK) RUNNING_TIME SEQUENCE FEE_AMOUNT SHOWING_TIME FEE_CURRENCY SELECT * FROM MOVIE as m LEFT JOIN SHOWING as s ON m.ID = s.MOVIE_ID 34 / 객체지향적인 도메인 레이어 구축하기
  35. 35. 객체 연관관계Association – 단방향UniDirectional MOVIE SHOWING ID(PK) ID(PK) TITLE MOVIE_ID(FK) RUNNING_TIME SEQUENCE FEE_AMOUNT SHOWING_TIME FEE_CURRENCY Movie Showing showing.getMovie(); calculateFee(showing) 1 * reserve(customer, count) Movie Showing movie.getShowings(); calculateFee(showing) 1 * reserve(customer, count) Movie Showing movie.getShowings(); calculateFee(showing) 1 * reserve(customer, count) showing.getMovie(); 35 / 객체지향적인 도메인 레이어 구축하기
  36. 36. 객체 협력Collaboration을 통한 구현  연관 관계는 책임 분배와 협력을 위한 핵심 메커니즘 Showing Showing 상영 정보를 알고 있다 Movie reserve() 예매 정보를 생성한다 * Movie 영화 정보를 알고 있다 Discount Strategy Movie 가격을 계산한다 1 calculateFee() DiscountStrategy 1 할인율 정책을 알고 있다 Rule 할인된 가격을 계산한다 DiscountStrategy 0..1 calculateFee() public class Showing { private Movie movie; public class Movie { private DiscountStrategy discountStrategy; public Money calculateFee() { return movie.calculateFee(this); public Money calculateFee(Showing showing) { } return discountStrategy.calculateFee(showing); ... } } ... } 36 / 객체지향적인 도메인 레이어 구축하기
  37. 37. Problem Data + Process = 젃차적인Procedural 프로그래밍 MOVIE SHOWING ID(PK) ID(PK) TITLE MOVIE_ID(FK) RUNNING_TIME SEQUENCE FEE_AMOUNT SHOWING_TIME FEE_CURRENCY Process Movie Showing Data id id ReservationService Movie Showing title movieIdreserveShowing() runningTime title fee calculateFee(showing) 1 * sequence reserve(customer, count) feeCurrency showingTime public class ReservationService { public Reservation reserveShowing(int customerId, int showingId, int audienceCount) { public class Showing showingDAO.selectShowing(showingId); Showing showing = { Movie movie = movieDAO.selectMovie(showing.getMovieId()); private Movie movie; long amount = calculateFee(movie.getFee(), showing, audienceCount); public Money calculateFee() { ... } return movie.calculateFee(this); } private long calculateFee(long movieFee, Showing showing, int audientCount) { ... } ... } } 37 / 객체지향적인 도메인 레이어 구축하기
  38. 38. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 38 / 객체지향적인 도메인 레이어 구축하기
  39. 39. Mismatch 캡슐화Encapsulation Flat Hierarchical Showing reserve(customer, count) Movie calculateFee(showing):Money {abstract} DiscountStrategy calculateFee(showing):Money {abstract} Rule isStatisfiedBy(showing) Amount Percent NonDiscount Strategy Strategy Strategy Sequence TimeOfDay Rule Rule 39 / 객체지향적인 도메인 레이어 구축하기
  40. 40. 할인 규칙 등록 {abstract} {abstract} Showing Movie DiscountStrategy Rule reserve(customer, count) 1 * calculateFee(showing) 1 0..1 calculateFee(showing) 1 0..* calculateFee(showing) Movie 캡슐화 경계Boundary 제 목 무지개여싞 상영 시간 116분 요 금 8,000원 AMOUNT Discount 할인 정책 DISCOUNT 할인 금액 9,000원 할인 규칙 SEQUENCE RULE Rule 할인 대상 1회 1회 5회 7회 40 / 객체지향적인 도메인 레이어 구축하기
  41. 41. Problem 캡슐화 저해 Flat 불변식 위반Invariant Violation Movie movie = movieDAO.selectMovie(1); movie.setFee(8000); DiscountStrategy strategy = new AmountDiscountStrategy(9000); discountStrategyDAO.save(strategy); DiscountRule rule = new SequenceRule(1); discountRuleDAO.save(rule); DiscountRule rule = new SequenceRule(1); discountRuleDAO.save(rule); 41 / 객체지향적인 도메인 레이어 구축하기
  42. 42. Conclusion 임피던스 불일치의 결과 Anemic Domain Model & Fat Service Layer public class Movie { public class ReservationService { private Long id; public Money calculateFee(Movie movie, private String title; DiscountStrategy strategy) { if (strategy.isAmountType()) { public Long getId() { ... return id; } else if (strategy.isPercentType()) { } ... } else { public String getTitle() { ... return title; } } ... } public class ReservationService { public Reservation reserveShowing(int customerId, int showingId, int audienceCount) { Showing showing = showingDAO.selectShowing(showingId); Movie movie = movieDAO.selectMovie(showing.getMovieId()); long amount = calculateFee(movie.getFee(), showing, audienceCount); 42 / 객체지향적인 도메인 레이어 구축하기
  43. 43. 아키텍처 패턴 User Interface Service Domain Infrastructure Transaction Script 43 / 객체지향적인 도메인 레이어 구축하기
  44. 44. 3. JPAJava Persistence API
  45. 45. DATA MAPPER 객체 모델과 DB 스키마 간의 독립성 유지 도메인 객체는 DB에 대해 독립적 ORMObject-Relational Mapper RULE ID Rule RuleMapper DISCOUNT_ID(FK) POSITION insert RULE_TYPE update DAY_OF_WEEK delete START_TIME SequenceRule TimeOfDayRule END_TUME SEQUENCE 45 / 객체지향적인 도메인 레이어 구축하기
  46. 46. JPAJava Persistence API Java ORM 표준 명세 Annotation과 XML을 이용한 META DATA MAPPING 기능 제공 Hibernate, EclipseLink RULE ID Rule JPA DISCOUNT_ID(FK) POSITION Hibernate RULE_TYPE DAY_OF_WEEK EclipseLink START_TIME SequenceRule TimeOfDayRule END_TUME SEQUENCE 46 / 객체지향적인 도메인 레이어 구축하기
  47. 47. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 47 / 객체지향적인 도메인 레이어 구축하기
  48. 48. Mismatch 구성 요소 크기Granularity의 불일치 MOVIE ID(PK) TITLE RUNNING_TIME Movie FEE_AMOUNT FEE_CURRENCY 제목 하나와 앨리스 Value Object 시간 135분 Entity <<value object>> running Duration Time 요금 quantity <<entity>> 8,000원 Movie title <<value object>> calculateFee(showing):Money Money amount currency fee 48 / 객체지향적인 도메인 레이어 구축하기
  49. 49. Solution @Embeddable Value Object Entity <<value object>> MOVIE running Duration Time ID(PK) quantity <<entity>> Movie TITLE RUNNING_TIME title <<value object>> FEE_AMOUNT calculateFee(showing):Money Money FEE_CURRENCY amount currency fee @Embeddable public class Duration { @Column(name="RUNNING_TIME", nullable=true) private long quantity; @Entity @Embeddable @Table(name="MOVIE") public class Money { public class Movie { @Column(name="FEE_AMOUNT", nullable=true) private Duration runningTime; private BigDecimal amount; private Money fee; @Column(name="FEE_CURRENCY", nullable=true) private Currency currency; 49 / 객체지향적인 도메인 레이어 구축하기
  50. 50. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 50 / 객체지향적인 도메인 레이어 구축하기
  51. 51. Mismatch 식별자 불일치Identity Mismatch MOVIE ID TITLE RUNNING_TIME FEE_AMOUNT FEE_CURRENCY 1 시간을 달리는 소녀 95 8,000 KRW 2 시간을 달리는 소녀 95 8,000 KRW movie1 : Movie movie2 : Movie title = ‚시간을 달리는 소녀‛ title = ‚시간을 달리는 소녀‛ runningTime = 95 runningTime = 95 Fee = 8000 Fee = 8000 51 / 객체지향적인 도메인 레이어 구축하기
  52. 52. Solution 영속 컨텍스트Persistence Context Begin Commit/ User Interface TX Rollback UNIT OF WORK Service IDENTITY MAP Domain Infrastructure 52 / 객체지향적인 도메인 레이어 구축하기
  53. 53. 영화 엔티티Entity 조회 MOVIE ID TITLE RUNNING_TIME FEE_AMOUNT FEE_CURRENCY 1 시간을 달리는 소녀 95 8,000 KRW 2 시간을 달리는 소녀 95 8,000 KRW movie1 : Movie movie2 : Movie title = ‚시간을 달리는 소녀‛ title = ‚시간을 달리는 소녀‛ runningTime = 95 runningTime = 95 Fee = 8000 Fee = 8000 53 / 객체지향적인 도메인 레이어 구축하기
  54. 54. 영속 컨텍스트Persistence Context Begin Commit/ User Interface TX Rollback UNIT OF WORK Service IDENTITY MAP movie1 : Movie title = ‚시간을 달리는 소녀‛ ID 1 runningTime = 95 Fee = 8000 Domain movie2 : Movie ID 2 title = ‚시간을 달리는 소녀‛ runningTime = 95 Fee = 8000 Infrastructure 54 / 객체지향적인 도메인 레이어 구축하기
  55. 55. 첫 번째 영화 엔티티 다시 조회 MOVIE ID TITLE RUNNING_TIME FEE_AMOUNT FEE_CURRENCY 1 시간을 달리는 소녀 95 8,000 KRW 2 시간을 달리는 소녀 95 8,000 KRW movie1 : Movie movie2 : Movie title = ‚시간을 달리는 소녀‛ title = ‚시간을 달리는 소녀‛ runningTime = 95 runningTime = 95 Fee = 8000 Fee = 8000 55 / 객체지향적인 도메인 레이어 구축하기
  56. 56. 영속 컨텍스트Persistence Context Begin Commit/ User Interface TX Rollback UNIT OF WORK Service IDENTITY MAP movie1 : Movie title = ‚시간을 달리는 소녀‛ ID 1 runningTime = 95 Fee = 8000 Domain movie2 : Movie ID 2 title = ‚시간을 달리는 소녀‛ runningTime = 95 Fee = 8000 Infrastructure 56 / 객체지향적인 도메인 레이어 구축하기
  57. 57. 식별자 일관성 보장 데이터베이스 주키Primary Key와 객체 식별자Identity 간 일관성 유지 MOVIE ID TITLE RUNNING_TIME FEE_AMOUNT FEE_CURRENCY 1 시간을 달리는 소녀 95 8,000 KRW 2 시간을 달리는 소녀 95 8,000 KRW movie1 : Movie movie2 : Movie title = ‚시간을 달리는 소녀‛ title = ‚시간을 달리는 소녀‛ runningTime = 95 runningTime = 95 Fee = 8000 Fee = 8000 57 / 객체지향적인 도메인 레이어 구축하기
  58. 58. 식별자 일관성 보장 movie1 = entityManager.load(Movie.class, 1); movie2 = entityManager.load(Movie.class, 1); assertSame(movie1, movie2); 58 / 객체지향적인 도메인 레이어 구축하기
  59. 59. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 59 / 객체지향적인 도메인 레이어 구축하기
  60. 60. Mismatch 다형성Polymorphism {abstract} Movie DiscountStrategy calculateFee(showing) registerDate Movie DiscountStrategy calculateFee(showing) id movieId title discountType runningTime amount fee percent Movie Discount feeCurrency registerDate Amount Percent calculateFee() Non calculateFee() DiscountStrategy DiscountStrategy DiscountStrategy Amount Discount 800원 discountAmount percent Percent Discount 10% public class ReservationService { public Money calculateFee(Movie movie, DiscountStrategy discountStrategy) { if (discountStrategy.isAmountType()) { ... No Discount 0원(%) } else if (discountStrategy.isPercentType()) { ... } else { ... } ... } } 60 / 객체지향적인 도메인 레이어 구축하기
  61. 61. Solution 상속 매핑Inheritance Mapping {abstract} DiscountStrategy registerDate calculateFee(showing) Amount Percent DiscountStrategy DiscountStrategy discountAmount percent Single Table Concrete Class Class Table Inheritance Inheritance Inheritance DISCOUNT AMOUNT_DISCOUNT DISCOUNT MOVIE_ID(FK) MOVIE_ID(FK) MOVIE_ID(FK) DISCOUNT_TYPE FEE_AMOUNT REGISTER_DATE FEE_AMOUNT FEE_CURRENCY FEE_CURRENCY REGISTER_DATE PERCENT REGISTER_DATE PERCENT_DISCOUNT AMOUNT_DISCOUN PERCENT_DISCOUN T T MOVIE_ID(FK) DISCOUNT_ID(FK) DISCOUNT_ID(FK) PERCENT FEE_AMOUNT PERCENT REGISTER_DATE FEE_CURRENCY 61 / 객체지향적인 도메인 레이어 구축하기
  62. 62. Solution 다형성을 통한 조건 분기 제거 {abstract} Movie DiscountStrategy Movie Discount calculateFee(showing) registerDate calculateFee(showing) Amount Discount 800원 Amount Percent Non DiscountStrategy DiscountStrategy DiscountStrategy Percent Discount 10% discountAmount percent public class Movie { No Discount 0원(%) private DiscountStrategy discountStrategy; public Money calculateFee(Showing showing) { return discountStrategy.calculateFee(showing); } } 62 / 객체지향적인 도메인 레이어 구축하기
  63. 63. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 63 / 객체지향적인 도메인 레이어 구축하기
  64. 64. Mismatch 연관관계Association와 외래키Foreign Key MOVIE SHOWING ID(PK) ID(PK) TITLE MOVIE_ID(FK) RUNNING_TIME SEQUENCE FEE_AMOUNT SHOWING_TIME FEE_CURRENCY Movie Showing showing.getMovie(); calculateFee(showing) 1 * reserve(customer, count) Movie Showing movie.getShowings(); calculateFee(showing) 1 * reserve(customer, count) Movie Showing movie.getShowings(); calculateFee(showing) 1 * reserve(customer, count) showing.getMovie(); 64 / 객체지향적인 도메인 레이어 구축하기
  65. 65. Solution 외래키 맵핑Foreign Key Mapping MOVIE SHOWING ID(PK) ID(PK) TITLE MOVIE_ID(FK) RUNNING_TIME SEQUENCE FEE_AMOUNT SHOWING_TIME FEE_CURRENCY Foreign Key public class Showing { @ManyToOne(optional=false) @JoinColumn(name="MOVIE_ID") private Movie movie; public Money calculateFee() { return movie.calculateFee(this); } } Association Movie Showing calculateFee(showing) 1 * reserve(customer, count) 65 / 객체지향적인 도메인 레이어 구축하기
  66. 66. 임피던스 불일치 유형 구성 요소 크기Granularity의 불일치 식별자Identity의 불일치 다형성Polymorphism의 불일치 연관 관계Association와 외래키Foreign Key의 불일치 캡슐화 경계Encapsulation Boundary의 불일치 66 / 객체지향적인 도메인 레이어 구축하기
  67. 67. Mismatch 캡슐화Encapsulation 불변식 위반Invariant Violation Movie movie = movieDAO.selectMovie(1); Hierarchical Flat movie.setFee(8000); Showing reserve(customer, count) DiscountStrategy strategy = new AmountDiscountStrategy(9000); Movie discountStrategyDAO.save(strategy); calculateFee(showing):Money {abstract} DiscountStrategy calculateFee(showing):Mon ey {abstract} Rule DiscountRule rule = new SequenceRule(1); isStatisfiedBy(sho wing) discountRuleDAO.save(rule);Amount Percent NonDiscoun tStrategy Strategy Strategy TimeOf Sequence Day Rule Rule DiscountRule rule = new SequenceRule(1); discountRuleDAO.save(rule); 67 / 객체지향적인 도메인 레이어 구축하기
  68. 68. Solution 페치 젂략Fetch Strategy 지연 페치Lazy Fetch public class Movie { @OneToOne(cascade=CascadeType.ALL, optional=true, fetch=FetchType.LAZY) private DiscountStrategy discountStrategy; public class DiscountStrategy { @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY) @JoinColumn(name="DISCOUNTID") private Set<Rule> rules = new HashSet<Rule>(); {abstract} {abstract} Showing Movie DiscountStrategy Rule Proxy Proxy 1 * calculateFee(showing) 1 0..1 calculateFee(showing) 1 0..* calculateFee(showing) reserve(customer, count) 68 / 객체지향적인 도메인 레이어 구축하기
  69. 69. Solution 페치 젂략Fetch Strategy 선행 페치Eager Fetch public class Movie { @OneToOne(cascade=CascadeType.ALL, optional=true, fetch=FetchType.EAGER) private DiscountStrategy discountStrategy; public class DiscountStrategy { @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn(name="DISCOUNTID") private Set<Rule> rules = new HashSet<Rule>(); {abstract} {abstract} Showing Movie DiscountStrategy Rule reserve(customer, count) 1 * calculateFee(showing) 1 0..1 calculateFee(showing) 1 0..* calculateFee(showing) 69 / 객체지향적인 도메인 레이어 구축하기
  70. 70. Solution Aggregate = 캡슐화 경계Encapsulation Boundary 예기치 못한 변경으로부터 보호 객체 그룹의 불변성 보장 Showing reserve(customer, count) Aggregate Movie {abstract} calculateFee(showing):Money DiscountStrategy calculateFee(showing):Money {abstract} Rule isStatisfiedBy(showing) Amount Percent NonDiscount Strategy Strategy Strategy Sequence TimeOfDay Rule Rule Eager Fetch Lazy Fetch 70 / 객체지향적인 도메인 레이어 구축하기
  71. 71. 4. 결롞
  72. 72. DOMAIN MODEL PATTERN 도메인을 구성하는 개념들을 따르는 도메인 레이어 적젃한 책임의 분배와 협력을 통한 객체 지향적인 도메인 레이어 72 / 객체지향적인 도메인 레이어 구축하기
  73. 73. 임피던스 불일치 맹목적으로 테이블의 구조를 따르는 객체 구조 젃차적인 TRANSACTION SCRIPT로 향하는 한 가지 이유 73 / 객체지향적인 도메인 레이어 구축하기
  74. 74. JPAJavaPersistece API 임피던스 불일치를 해결할 수 있는 실용적인 솔루션 풍부한 도메인 레이어Rich Domain Layer의 기반 74 / 객체지향적인 도메인 레이어 구축하기
  75. 75. Domain Model에 초점을 맞춰라 Showing Reservation Reservation Showing 1 <<create>> 0..* reserve(customer, count):Reservation Customer 0..* {abstract} {abstract} Movie DiscountStrategy Rule 1 calculateFee(showing):Money calculateFee(showing):Money isStatisfiedBy(showing):boolean 1 0..1 1 1..* Amount Percent NonDiscount Sequence TimeOfDay Strategy Strategy Strategy Rule Rule Movie Discount Rule 75 / 객체지향적인 도메인 레이어 구축하기
  76. 76. Data Model이 더 중요 76 / 객체지향적인 도메인 레이어 구축하기
  77. 77. 타협하라 Be Pragmatic 데이터베이스가 하나의 객체 저장소로 보여진다면 매핑 도구의 기능과는 상관없이 데이터 모델과 객체 모델이 서로 갈라지게 해서는 안 된다. 일부 객체 관계의 풍부함을 희생해서 관계 모델에 밀접하게 한다. 객체 매핑을 단순화하는데 도움이 된다면 정규화와 같은 정형 화된 관계 표준을 젃충한다. - Eric Evans 77 / 객체지향적인 도메인 레이어 구축하기
  78. 78. Thank you.78 / 객체지향적인 도메인 레이어 구축하기
  79. 79. Question?79 / 객체지향적인 도메인 레이어 구축하기
  80. 80. 참고자료- Christian Bauer, Gavin King, Java Persistence with Hibernate, Manning, 2006.- Michael Keith, Merrick Schincario, Pro JPA2 : Mastering the Java(TM) Persistence API, Apress, 2009.- Chris Richardson, POJOs in Action : Developing Enterprise Applications with Lightweight Frameworks, Manning, 2006.- Martin Fowler, Patterns of Enterprise Application Architecture, Addison-Wesley, 2002.- Eric Evans, Domain-Driven Design, Addison-Wesley, 2003.- Kent Beck and Ward Cunningham, ‚A Laboratory for Teaching Object Oriented Thinking,‛ OOPSLA ‘89 Conference Proceedings, SIGPLAN Notices, 24(10), pp. 1-6, New Orleans, Louisiana, October 1989.- Rebecca Wirfs-Brock and Brian Wilkerson, ‚Object-Oriented Design: A Responsibility-Driven Approach,‛ OOPSLA ‘89 Conference Proceedings, SIGPLAN Notices, 24(10), pp.71-76, New Orleans, Louisiana, October, 1989.- Rebecca Wirfs-Brock, Alan McKean, Object Design : Roles, Responsibilities, and Collaborations , Addison- Wesley, 2002. 80 / 객체지향적인 도메인 레이어 구축하기
  81. 81. Appendix A. CRC Card
  82. 82. 예매 생성 책임 예매 생성에 필요한 정보의 EXPERT에게 할당Creator Showing 상영 정보를 알고 있다 예매 정보를 생성한다 82 / 객체지향적인 도메인 레이어 구축하기
  83. 83. 가격 계산 책임 영화 가격 정보를 알고 있는 EXPERT에 할당Information Expert Movie Showing 영화 정보를 알고 있다 가격을 계산한다 상영 정보를 알고 있다 Movie 예매 정보를 생성한다 83 / 객체지향적인 도메인 레이어 구축하기
  84. 84. 할인율 계산 책임 할인율을 적용할 STRATEGY 객체 추가 Movie Showing 영화 정보를 알고 있다 Discount Strategy 가격을 계산한다 상영 정보를 알고 있다 Movie 예매 정보를 생성한다 DiscountStrategy 할인율 정책을 알고 있다 할인된 가격을 계산한다 84 / 객체지향적인 도메인 레이어 구축하기
  85. 85. 할인 여부를 판단할 책임 할인 정책을 판단하기 위한 SPECIFICATION 객체 추가 Movie Showing 영화 정보를 알고 있다 Discount Strategy 가격을 계산한다 상영 정보를 알고 있다 Movie 예매 정보를 생성한다 DiscountStrategy 할인율 정책을 알고 있다 Rule 할인된 가격을 계산한다 Rule 할인 정책을 알고 있다 Showing 할인 여부를 판단한다 85 / 객체지향적인 도메인 레이어 구축하기
  86. 86. Appendix B. Domain Model Pattern Implementation
  87. 87. Domain Layer Collaborationpublic class Showing { public Reservation reserve(Customer customer, int audienceCount) { return new Reservation(customer, this, audienceCount); }} public class Reservation { public Reservation(Customer customer, Showing showing, int audienceCount) { this.customer = customer; this.showing = showing; this.fee = showing.calculateFee().times(audienceCount); this.audienceCount = audienceCount; } } public class Showing { public Money calculateFee() { return movie.calculateFee(this); } } public class Movie { public Money calculateFee(Showing showing) { return discountStrategy.calculateFee(showing); } } 87 / 객체지향적인 도메인 레이어 구축하기
  88. 88. Domain Layer Collaborationpublic abstract class DiscountStrategy { public Money calculateFee(Showing showing) { for(Rule each : rules) { if (each.isStatisfiedBy(showing)) { return getDiscountedFee(showing); } } return showing.getFixedFee(); } abstract protected Money getDiscountedFee(Showing showing); public abstract class Rule { abstract public boolean isStatisfiedBy(Showing showing); } public class SequenceRule extends Rule { public boolean isStatisfiedBy(Showing showing) { return showing.isSequence(sequence); } } public class TimeOfDayRule extends Rule { public boolean isStatisfiedBy(Showing showing) { return showing.isPlayingOn(dayOfWeek) && Interval.closed(startTime, endTime) .includes(showing.getPlayngInterval()); } } 88 / 객체지향적인 도메인 레이어 구축하기
  89. 89. Domain Layer Collaborationpublic abstract class DiscountStrategy { public Money calculateFee(Showing showing) { for(Rule each : rules) { if (each.isStatisfiedBy(showing)) { return getDiscountedFee(showing); } } return showing.getFixedFee(); } abstract protected Money getDiscountedFee(Showing showing); public class AmountDiscountStrategy extends DiscountStrategy { protected Money getDiscountedFee(Showing showing) { return showing.getFixedFee().minus(discountAmount); } } public class NonDiscountStrategy extends DiscountStrategy { protected Money getDiscountedFee(Showing showing) { return showing.getFixedFee(); } } public class PercentDiscountStrategy extends DiscountStrategy { protected Money getDiscountedFee(Showing showing) { return showing.getFixedFee().minus(showing.getFixedFee().times(percent)); } } 89 / 객체지향적인 도메인 레이어 구축하기
  90. 90. Domain Layer Collaboration :Showing :Reservation :Movie :DiscountStrategy :Rule reserve() new calculateFee() calculateFee() calculateFee() * isStatisfied() 90 / 객체지향적인 도메인 레이어 구축하기
  91. 91. Data Model RESERVATION CUSTOMER ID ID CUSTOMER_ID(FK) CUSTOMER_ID SHOWING_ID(FK) NAME FEE_AMOUNT FEE_CURRENCY AUDIENCE_COUNT RULE SHOWING MOVIE DISCOUNT ID ID ID MOVIE_ID(FK) DISCOUNT_ID(FK) MOVIE_ID(FK) TITLE DISCOUNT_TYPE POSITION SEQUENCE RUNNING_TIME FEE_AMOUNT RULE_TYPE SHOWING_TIME FEE_AMOUNT FEE_CURRENCY DAY_OF_WEEK FEE_CURRENCY PERCENT START_TIME REGISTER_DATE END_TUME SEQUENCE 91 / 객체지향적인 도메인 레이어 구축하기
  92. 92. Appendix C. Impedance Mismatch Summary
  93. 93. 임피던스 불일치Impedance Mismatch MOVIE running Duration Time ID(PK) quantity Movie TITLE RUNNING_TIME title Money FEE_AMOUNT FEE_CURRENCY amount fee currency Movie Showing MOVIE SHOWING 1 * ID(PK) ID(PK) Movie Showing TITLE MOVIE_ID(FK) SEQUENCE 1 * RUNNING_TIME FEE_AMOUNT SHOWING_TIME FEE_CURRENCY Movie Showing 1 * AMOUNT_ {abstract} DISCOUNT DISCOUNT DiscountStrategy MOVIE_ID(FK) MOVIE_ID(FK) registerDate DISCOUNT REGISTER_DATE FEE_AMOUNT MOVIE_ID(FK) FEE_CURRENCY REGISTER_DATE DISCOUNT_TYPE Amount Percent Non FEE_AMOUNT PERCENT_ AMOUNT_ PERCENT_ FEE_CURRENCY Discount Discount Discount PERCENT DISCOUNT DISCOUNT DISCOUNT Strategy Strategy Strategy REGISTER_DATE MOVIE_ID(FK) DISCOUNT_ID(FK) DISCOUNT_ID(FK) discountAmount percent PERCENT FEE_AMOUNT PERCENT REGISTER_DATE FEE_CURRENCY 93 / 객체지향적인 도메인 레이어 구축하기

×