70
Object-Oriented Design & Architecture Rich Domain Model 조영호 Eternity’s Chit-Chat http://aeternum.egloos.com

Rich domain model

Embed Size (px)

Citation preview

Page 1: Rich domain model

Object-Oriented Design & Architecture

Rich Domain Model

조영호

Eternity’s Chit-Chat

http://aeternum.egloos.com

Page 2: Rich domain model

2. 데이터-지향 설계

3. 책임-주도 설계

목차

4. 아키텍처 & 프레임워크

1. 영화 예매 시스템 도메인

5. 결롞

Page 3: Rich domain model

1. 영화 예매 시스템 도메인

Page 4: Rich domain model

4 / 문서의 제목

온라인 영화 예매 시스템

Page 5: Rich domain model

5 / 문서의 제목

Domain Concept - 영화

Movie

Page 6: Rich domain model

6 / 문서의 제목

Domain Concept - 상영

2010-10-20 09:30 조조

Showing2010-10-21 20:30 5회

2010-12-01 14:20 4회

Page 7: Rich domain model

7 / 문서의 제목

Domain Concept – 할인 정책

Discount Amount Discount

Percent Discount

\8,000 - \800 = \7,200

\8,000 – (\8,000 * 0.1) = \7,200

Page 8: Rich domain model

8 / 문서의 제목

Domain Concept – 할인 규칙

Rule Sequence Rule

Time Rule

조조 상영인 경우

월요일 10:00 ~ 12:00 상영인 경우

목요일 18:00 ~ 21:00 상영인 경우

10회 상영인 경우

Page 9: Rich domain model

9 / 문서의 제목

Domain Concept –할인 정책 + 할인 규칙

Movie Discount Rule

1 0..1 1 1..*

Page 10: Rich domain model

10 / 문서의 제목

10회 상영인 경우

Domain Concept –할인 정책 + 할인 규칙

Movie Discount Rule

1 0..1 1 1..*

이끼8000원

Amount DC800원

조조 상영인 경우

월요일 10:00 ~ 12:00 상영인 경우

목요일 18:00 ~ 21:00 상영인 경우

Page 11: Rich domain model

11 / 문서의 제목

10회 상영인 경우

Domain Concept –할인 적용

이끼8000원

Amount DC800원

조조 상영인 경우

월요일 10:00 ~ 12:00 상영인 경우

목요일 18:00 ~ 21:00 상영인 경우

상영정보

2010년 12월 23일 목요일

18:00 ~ 20:00(7회차)

Page 12: Rich domain model

12 / 문서의 제목

10회 상영인 경우

Domain Concept –할인 적용

이끼8000원

Amount DC800원

조조 상영인 경우

월요일 10:00 ~ 12:00 상영인 경우

목요일 18:00 ~ 21:00 상영인 경우

상영정보

2010년 12월 23일 목요일

18:00 ~ 20:00(7회차)

\7,200

Page 13: Rich domain model

13 / 문서의 제목

Domain Concept –예매

Reservation이끼

2010년 12월 23일 (목)7회 6:00(오후) – 8:00(오후)

2명

16,000원

14,400원

제 목

상영 정보

인 원

정 가

결재 금액

Page 14: Rich domain model

2. 데이터-지향 설계

Page 15: Rich domain model

15 / 문서의 제목

무엇을 저장할 것인가 - 데이터

Page 16: Rich domain model

16 / 문서의 제목

데이터 모델

MOVIE

ID

TITLERUNNING_TIMEFEE_AMOUNTFEE_CURRENCY

RESERVATION

ID

CUSTOMER_ID(FK)SHOWING_ID(FK)FEE_AMOUNTFEE_CURRENCYAUDIENCE_COUNT

RULE

ID

DISCOUNT_ID(FK)POSITIONRULE_TYPEDAY_OF_WEEKSTART_TIMEEND_TUMESEQUENCE

DISCOUNT

MOVIE_ID(FK)

DISCOUNT_TYPEFEE_AMOUNTFEE_CURRENCYPERCENT

SHOWING

ID

MOVIE_ID(FK)SEQUENCESHOWING_TIME

CUSTOMER

ID

CUSTOMER_IDNAME

Page 17: Rich domain model

17 / 문서의 제목

또 다른 데이터 표현 – Anemic Domain Model

Movie

idtitlerunningTimefee

Reservation

idcustomerIdshowingIdAmounraudienceCount

Rule

iddiscountIdpositionruleTypedayOfWeekstartTimeendTimesequence

Discount

movieIddiscountTypeamountpercent

Showing

idmovieIdsequenceshowingTime

Customer

IdcustomerIdname

Page 18: Rich domain model

18 / 문서의 제목

초기 데이터

ID TITLE RUNNING_TIME FEE_AMOUNT FEE_CURRENCY

1 이끼 120 8000 KRW

MOVIE

MOVIE_ID DISCOUNTYPE FEE_AMOUNT FEE_ACURRENCY PERCENT

1 A 800 KRW NULL

DISCOUNT

ID DISCOUNT_ID POSITION RULE_TYPE DAY_OF_WEEK

1 1 0 S NULL

RULE

START_TIME

NULL

END_TIME

NULL

SEQUENCE

1

2 1 1 S NULL NULL NULL 10

3 1 2 T 2 10:00 12:00 NULL

4 1 3 T 5 18:00 21:00 NULL

ID MOVIE_ID SEQUENCE SHOWING_TIME

1 1 7 2010-12-23 18:00

SHOWING

Page 19: Rich domain model

19 / 문서의 제목

어떻게 처리할 것인가 - 프로세스

Page 20: Rich domain model

20 / 문서의 제목

예매 처리 Service

<<interface>>

MovieDAO

<<interface>>

ReservationService

reserveShowing(customerId, showingId, audienceCount)

ReservationServiceImpl

reserveShowing(customerId, showingId, audienceCount)

<<interface>>

DiscountDAO

<<interface>>

RuleDAO

<<interface>>

ShowingDAO

<<interface>>

ReservationDAO

Page 21: Rich domain model

21 / 문서의 제목

데이터를 사용한 예매 프로세스 구현

@Override

public Reservation reserveShowing(int customerId, int showingId, int audienceCount) {

① 데이터베이스로부터 Movie와 Showing 정보 로딩

② 데이터베이스로부터 Rule 정보 로딩 후 Showig에 적용할 수 있는 Rule 이 있는지 판단

③ if (Rule 이 존재하면) {Discount를 읽어 요금 할인된 요금 계산

} else {Movie에 저장되어 있는 정액 요금 사용

}

④ Reservation 생성 후 데이터베이스 저장}

Algorithm or Process

Page 22: Rich domain model

22 / 문서의 제목

데이터를 사용한 예매 프로세스 구현

@Override

public Reservation reserveShowing(int customerId, int showingId, int audienceCount) {

Showing showing = showingDAO.selectShowing(showingId);

Movie movie = movieDAO.selectMovie(showing.getMovieId());

② 데이터베이스로부터 Rule 정보 로딩 후 Showig에 적용할 수 있는 Rule 이 있는지 판단

③ if (Rule 이 존재하면) {Discount를 읽어 요금 할인된 요금 계산

} else {Movie에 저장되어 있는 정액 요금 사용

}

④ Reservation 생성 후 데이터베이스 저장}

① 데이터베이스로부터 Movie와 Showing 정보 로딩

Page 23: Rich domain model

23 / 문서의 제목

데이터를 사용한 예매 프로세스 구현

@Override

public Reservation reserveShowing(int customerId, int showingId, int audienceCount) {

Showing showing = showingDAO.selectShowing(showingId);

Movie movie = movieDAO.selectMovie(showing.getMovieId());

Rule rule = findRule(showing, movie);

③ if (Rule 이 존재하면) {Discount를 읽어 요금 할인된 요금 계산

} else {Movie에 저장되어 있는 정액 요금 사용

}

④ Reservation 생성 후 데이터베이스 저장}

private Rule findRule(Showing showing, Movie movie) {

for(Rule each : ruleDAO.selectRules(movie.getId())) {

if (each.isAccepted(showing, movie)) {

return each;

}

}

return null;

}

② 데이터베이스로부터 Rule 정보 로딩 후 Showig에 적용할 수 있는 Rule 이 있는지 판단

Page 24: Rich domain model

24 / 문서의 제목

데이터를 사용한 예매 프로세스 구현

@Override

public Reservation reserveShowing(int customerId, int showingId, int audienceCount) {

Showing showing = showingDAO.selectShowing(showingId);

Movie movie = movieDAO.selectMovie(showing.getMovieId());

Rule rule = findRule(showing, movie);

Money fee = movie.getFee();

if (rule != null) {

fee = calculateFee(movie);

}

④ Reservation 생성 후 데이터베이스 저장}

③ if (Rule 이 존재하면) {Discount를 읽어 요금 할인된 요금 계산

} else {Movie에 저장되어 있는 정액 요금 사용

}

private Money calculateFee(Movie movie) {Discount discount = discountDAO.selectDiscount(movie.getId());

if (discount.isAmountType()) {return movie.getFee().minus(Money.wons(discount.getFee()));

} else if (discount.isPercentType()) {return movie.getFee().minus(

movie.getFee().times(discount.getPercent()));

}

return movie.getFee();}

Page 25: Rich domain model

25 / 문서의 제목

데이터를 사용한 예매 프로세스 구현

@Override

public Reservation reserveShowing(int customerId, int showingId, int audienceCount) {

Showing showing = showingDAO.selectShowing(showingId);

Movie movie = movieDAO.selectMovie(showing.getMovieId());

Rule rule = findRule(showing, movie);

Money fee = movie.getFee();

if (rule != null) {

fee = calculateFee(movie);

}

Reservation result = makeReservation(customerId, showingId, audienceCount, fee);

reservationDAO.insert(result);

return result;

}

④ Reservation 생성 후 데이터베이스 저장

private Reservation makeReservation(int customerId, int showingId,

int audienceCount, Money payment) {

Reservation result = new Reservation();

result.setCustomerId(customerId);

result.setShowingId(showingId);

result.setAudienceCount(audienceCount);

result.setFee(payment);

return result;

}

Page 26: Rich domain model

26 / 문서의 제목

중앙 집중식Centralized 제어 스타일

reserveShowing()

showing = selectShowing()

rules = selectRules()

isAccepted()*

discount = selectDiscount()

isAmountType()

getFee()

new

rules:Rule

:ShowingDAO

showing:Showing

:ReservationService

:RuleDAO

:DiscountDAO

discount:Discount

:Reservation

Page 27: Rich domain model

27 / 문서의 제목

아키텍처 패턴

Transaction Script

Page 28: Rich domain model

3. 책임-주도 설계

Page 29: Rich domain model

29 / 문서의 제목

책임Responsibility

Page 30: Rich domain model

30 / 문서의 제목

Showing

상영 정보를 알고 있다

예매 생성 책임

예매 생성에 필요한 정보의 EXPERT에게 할당Creator

예매 정보를 생성한다

Page 31: Rich domain model

31 / 문서의 제목

가격 계산 책임

영화 가격 정보를 알고 있는 EXPERT에 할당Information Expert

Showing

상영 정보를 알고 있다

예매 정보를 생성한다

Movie

Customer

Movie

영화정보를 알고 있다

가격을 계산한다

Page 32: Rich domain model

32 / 문서의 제목

Showing

상영 정보를 알고 있다

Movie

영화정보를 알고 있다 DiscountStrategy

할인율 계산 책임

할인율을 적용할 STRATEGY 객체 추가

DiscountStrategy

할인율 정책을 알고 있다

할인된 가격을 계산한다

예매 정보를 생성한다

Movie

Customer

가격을 계산한다

Page 33: Rich domain model

33 / 문서의 제목

Showing

상영 정보를 알고 있다

Movie

영화정보를 알고 있다 DiscountStrategy

DiscountStrategy

할인율 정책을 알고 있다

할인된 가격을 계산한다

예매 정보를 생성한다

Movie

Customer

가격을 계산한다

할인 여부를 판단할 책임

할인 정책을 판단하기 위한 SPECIFICATION 객체 추가

Rule

할인 정책을 알고 있다

할인 여부를 판단한다

Rule

Showing

Page 34: Rich domain model

34 / 문서의 제목

Rich Domain Model

Customer

Showing

reserve(customer, count):Reservation

Rule

isStatisfiedBy(showing):boolean

Reservation

AmountStrategy PercentStrategy NonDiscountStrategy SequenceRule TimeOfDayRule

DiscountStrategy

calculateFee(showing):Money

Movie

calculateFee(showing):Money

상속inheritance과 다형성polymorphism의 활용

<<create>>

Page 35: Rich domain model

35 / 문서의 제목

데이터에 대한 걱정은 잠시 꺼두셔도 좋습니다

Page 36: Rich domain model

36 / 문서의 제목

public 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);

}

}

책임 기반 구현

Page 37: Rich domain model

37 / 문서의 제목

public 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());

}

}

책임 기반 구현

Page 38: Rich domain model

38 / 문서의 제목

public 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));

}

}

Page 39: Rich domain model

39 / 문서의 제목

위임식delegated, 분산식dispersed 제어 스타일

:Reservation :Movie

reserve()

new

:Showing

calculateFee()

calculateFee()

:DiscountStrategy :Rule

calculateFee()

isStatisfied()*

Page 40: Rich domain model

40 / 문서의 제목

아키텍처 패턴

Domain Model

Page 41: Rich domain model

41 / 문서의 제목

Transaction Script의 단점

@Override

public Reservation reserveShowing(int customerId, int showingId, int audienceCount) {

Showing showing = showingDAO.selectShowing(showingId);

Movie movie = movieDAO.selectMovie(showing.getMovieId());

Rule rule = findRule(showing, movie);

Money fee = movie.getFee();

if (rule != null) {

fee = calculateFee(movie);

}

Reservation result = makeReservation(customerId, showingId, audienceCount, fee);

reservationDAO.insert(result);

return result;

}

private Money calculateFee(Movie movie) {Discount discount = discountDAO.selectDiscount(movie.getId());

if (discount.isAmountType()) {return movie.getFee().minus(Money.wons(discount.getFee()));

} else if (discount.isPercentType()) {return movie.getFee().minus(

movie.getFee().times(discount.getPercent()));

}

return movie.getFee();}

새로운 할인 정책 추가

Page 42: Rich domain model

42 / 문서의 제목

@Override

public Reservation reserveShowing(int customerId, int showingId, int audienceCount) {

Showing showing = showingDAO.selectShowing(showingId);

Movie movie = movieDAO.selectMovie(showing.getMovieId());

Rule rule = findRule(showing, movie);

Money fee = movie.getFee();

if (rule != null) {

fee = calculateFee(movie);

}

Reservation result = makeReservation(customerId, showingId, audienceCount, fee);

reservationDAO.insert(result);

return result;

}

private Money calculateFee(Movie movie) {

Discount discount = discountDAO.selectDiscount(movie.getId());

if (discount.isAmountType()) {return movie.getFee().minus(Money.wons(discount.getFee()));

} else if (discount.isPercentType()) {return movie.getFee().minus(

movie.getFee().times(discount.getPercent()));} else if (discount.isMilleageType()) {

return movie.getFee().minus(movie.getMileageBaseAmount().times(discount.getMileageFactor()));

}

return movie.getFee();}

기졲 코드 수정

Transaction Script의 단점

Page 43: Rich domain model

43 / 문서의 제목

Rich Domain Model의 장점

Customer

Showing

reserve(customer, count):Reservation

Rule

isStatisfiedBy(showing):boolean

Reservation

AmountStrategy PercentStrategy NonDiscountStrategy SequenceRule TimeOfDayRule

DiscountStrategy

calculateFee(showing):Money

Movie

calculateFee(showing):Money

<<create>>

새로운 할인 정책 추가

Page 44: Rich domain model

44 / 문서의 제목

Rich Domain Model의 장점

Customer

Showing

reserve(customer, count):Reservation

Rule

isStatisfiedBy(showing):boolean

Reservation

AmountStrategy PercentStrategy NonDiscountStrategy SequenceRule TimeOfDayRule

DiscountStrategy

calculateFee(Showing):Money

Movie

calculateFee(showing):Money

<<create>>

MileageStrategy

OCPOpen-Closed Principle

Page 45: Rich domain model

4. 아키텍처 & 프레임워크

Page 46: Rich domain model

46 / 문서의 제목

Layered Architecture

User Interface

Service

Domain

Infrastructure

Page 47: Rich domain model

47 / 문서의 제목

도메인 레이어 캡슐화

Page 48: Rich domain model

48 / 문서의 제목

Layered Architecture

User Interface

Service

Domain

Infrastructure

Page 49: Rich domain model

49 / 문서의 제목

Service Layer

애플리케이션 경계 도메인 레이어의 재사용성 촉짂

<<interface>>

ReservationService

reserveShowing(customerId, showingId, audienceCount)

ReservationServiceImpl

reserveShowing(customerId, showingId, audienceCount)

<<interface>>

CustomerRepository

<<interface>>

ShowingRepository

<<interface>>

ReservationRepository

Showing

Page 50: Rich domain model

50 / 문서의 제목

Service Layer

Operation Script Not Transaction Script

<<interface>>

ReservationService

reserveShowing(customerId, showingId, audienceCount)

ReservationServiceImpl

reserveShowing(customerId, showingId, audienceCount)

<<interface>>

CustomerRepository

<<interface>>

ShowingRepository

<<interface>>

ReservationRepository

Showing

@Override

@Transactional(propagation=Propagation.REQUIRED)

public Reservation reserveShowing(int reserverId, int showingId,

int audienceCount) {

Customer reserver = customerRepository.find(reserverId);

Showing showing = showingRepository.find(showingId);

Reservation reservation = showing.reserve(reserver, audienceCount);

reservationRepository.save(reservation);

return reservation;

}

Page 51: Rich domain model

51 / 문서의 제목

도메인 레이어 의졲성 관리

User Interface

Service

Domain

Infrastructure

Page 52: Rich domain model

52 / 문서의 제목

순수한 객체

POJOPlain Old Java Object

Page 53: Rich domain model

53 / 문서의 제목

POJO의 3대 요소

Dependency Injection

Aspect-Oriented Programming

Annotation

Page 54: Rich domain model

54 / 문서의 제목

비침투적인Non-Intrusive 프레임워크

POJO 개발을 위한 젂제조건 Lightweight Framework

Page 55: Rich domain model

55 / 문서의 제목

Dependency Injection

객체 간의 의졲성 관리 이슈로부터 도메인 레이어 보호

구성-사용 분리 원리the principle of separating configuration from use

<<interface>>

ReservationService

reserveShowing(customerId, showingId, audienceCount)

ReservationServiceImpl

reserveShowing(customerId, showingId, audienceCount)

<<interface>>

CustomerRepository

CustomerRepositoryImpl

Page 56: Rich domain model

56 / 문서의 제목

Dependency Injection – Spring

<bean id="reservationService”

class="org.eternity.theater.reservation.ReservationServiceImpl">

<property name="customerRepository" ref="customerRepository"/>

......

</bean>

<bean id="customerRepository“

class="org.eternity.theater.customer.hibernate.CustomerRepositoryImpl">

<property name="sessionFactory" ref="sessionFactory"/>

</bean>

<<interface>>

ReservationService

reserveShowing(customerId, showingId, audienceCount)

ReservationServiceImpl

reserveShowing(customerId, showingId, audienceCount)

<<interface>>

CustomerRepository

CustomerRepositoryImpl

Page 57: Rich domain model

57 / 문서의 제목

Impedance Mismatch

객체 모델과 DB 스키마 간의 불일치

객체 모델과 DB 스키마 간의 변환 계층 필요

RULE

ID

DISCOUNT_ID(FK)

POSITION

RULE_TYPE

DAY_OF_WEEK

START_TIME

END_TUME

SEQUENCE

DISCOUNT

MOVIE_ID(FK)

DISCOUNT_TYPE

FEE_AMOUNT

FEE_CURRENCY

PERCENT

Rule

Amount

Strategy

Percent

Strategy

NonDiscount

Strategy

Sequence

Rule

TimeOfDay

Rule

DiscountStrategy

Page 58: Rich domain model

58 / 문서의 제목

DATA MAPPER

객체 모델과 DB 스키마 간의 독립성 유지

도메인 객체는 DB에 대해 독립적

RULE

ID

DISCOUNT_ID(FK)

POSITION

RULE_TYPE

DAY_OF_WEEK

START_TIME

END_TUME

SEQUENCE

Rule

SequenceRule TimeOfDayRule

RuleMapper

insert

Update

delete

Page 59: Rich domain model

59 / 문서의 제목

O/R MAPPER - Hibernate

<hibernate-mapping package="org.eternity.theater.movie.pricing" default-access="field"><class name="Rule" table="RULE">

<id name="id" column="ID" type="long"><generator class="native"/>

</id>

<discriminator column="RULE_TYPE" type="string" />

<subclass name="SequenceRule" discriminator-value="S"><property name="sequence" column="SEQUENCE" type="integer"/>

</subclass>

<subclass name="TimeOfDayRule" discriminator-value="A"><property name="dayOfWeek" column="DAY_OF_WEEK" type="integer"/><property name="startTime" column="START_TIME"

type="org.eternity.support.hibernate.TimeOfDayUserType"/><property name="endTime" column="END_TIME"

type="org.eternity.support.hibernate.TimeOfDayUserType"/></subclass>

</class></hibernate-mapping>

RULE

ID

DISCOUNT_ID(FK)POSITIONRULE_TYPEDAY_OF_WEEKSTART_TIMEEND_TUMESEQUENCE

Rule

SequenceRule TimeOfDayRule

Page 60: Rich domain model

60 / 문서의 제목

트랜잭션 경계

User Interface

Service

Domain

Infrastructure

Begin TXCommit

Rollback

Page 61: Rich domain model

61 / 문서의 제목

AOPAspect Oriented Programming

User Interface

Service

Domain

Infrastructure

Begin TXCommit

Rollback

ASPECT

Page 62: Rich domain model

62 / 문서의 제목

Spring AOP & Annotation

User Interface

Service

Domain

Infrastructure

Begin TXCommit

Rollback

ASPECT

<tx:annotation-driven/>

<bean id="transactionManager"

class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory"/>

</bean>

@Override

@Transactional(propagation=Propagation.REQUIRED)

public Reservation reserveShowing(int reserverId, int showingId, int audienceCount) {

Customer reserver = customerRepository.find(reserverId);

Showing showing = showingRepository.find(showingId);

Reservation reservation = showing.reserve(reserver, audienceCount);

reservationRepository.save(reservation);

return reservation;

}

Page 63: Rich domain model

5. 결롞

Page 64: Rich domain model

64 / 문서의 제목

Rich Domain Model

설계 관점이지 기술 관점이 아님

훌륭한 객체 지향 설계 지침을 따를 것

Page 65: Rich domain model

65 / 문서의 제목

그러나 기술적인 제약 사항 역시 중요

비침투적인 프레임워크를 사용하라

프레임워크의 제약 사항을 파악하라

프레임워크의 제약 사항에 따라 구현 가능하도록 아키텍처를 수정하라

가지고 있는 도구 또한 아키텍처에 영향을 준다는 사실을 알 수 있다. 때로는 아키

텍처를 바탕으로 도구를 선택할 수 있으며, 이롞적으로는 그것이 올바른 방법이다.

그러나 실제로는 도구에 아키텍처를 맞추어야 한다.

- Martin Fowler

Page 66: Rich domain model

66 / 문서의 제목

Rich Domain Model을 자제해야 하는 경우

객체 지향 분석/설계 경험이 부족한 경우

비침투적인 프레임워크를 사용할 수 없는 경우

비침투적인 프레임워크에 대한 경험이 부족한 경우

O/R Mapper를 사용할 수 없는 경우

비즈니스 로직이 단순하고 개발 기간이 짧은 경우

Page 67: Rich domain model

67 / 문서의 제목

첨언

Be Pragmatic

Page 68: Rich domain model

Thank you.

Page 69: Rich domain model

Question.

Page 70: Rich domain model

70 / 문서의 제목

참고자료

- Patterns of Enterprise Application Architecture, Martin Fowler, Addison-Wesley, 2002

- Domain-Driven Design, Eric Evans, Addison-Wesley, 2003

- Expert One-on-One J2EE Development without EJB, Rod Johnson, Wrox, 2004

- Applying UML and Patterns 3rd Edition, Craig Larman, Prentice Hall, 2004

- Agile Software Development, Principles, Patterns, and Practices, Robert C. Martin,

Prentice Hall, 2002

- Object Design : Roles, Responsibilities, and Collaborations , Rebecca Wirfs-Brock,

Alan McKean, Addison-Wesley,2002

- POJOs in Action, Chris Richardson, Manning, 2006

- Java Persistence with Hibernate, Christian Bauer, Gavin King, Manning, 2006

- Spring in Action 2nd Edition, Craig Walls, Manning, 2007

- The New Holy Trinity, Ramnivas Laddad,

http://www.aspectprogrammer.org/blogs/adrian/2005/03/the_new_holy_tr.html